diff options
Diffstat (limited to 'platform/darwin/test')
21 files changed, 1658 insertions, 976 deletions
diff --git a/platform/darwin/test/MGLBackgroundStyleLayerTests.mm b/platform/darwin/test/MGLBackgroundStyleLayerTests.mm index e7c2982413..de8080f425 100644 --- a/platform/darwin/test/MGLBackgroundStyleLayerTests.mm +++ b/platform/darwin/test/MGLBackgroundStyleLayerTests.mm @@ -42,7 +42,7 @@ @"backgroundColor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"%@", [MGLColor redColor]]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.backgroundColor = functionExpression; mbgl::style::IntervalStops<mbgl::Color> intervalStops = {{ @@ -66,8 +66,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.backgroundColor = functionExpression, NSException, NSInvalidArgumentException, @"MGLBackgroundLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.backgroundColor = functionExpression, NSException, NSInvalidArgumentException, @"MGLBackgroundLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.backgroundColorTransition = transitionTest; @@ -95,7 +95,7 @@ @"backgroundOpacity should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.backgroundOpacity = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -119,8 +119,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.backgroundOpacity = functionExpression, NSException, NSInvalidArgumentException, @"MGLBackgroundLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.backgroundOpacity = functionExpression, NSException, NSInvalidArgumentException, @"MGLBackgroundLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.backgroundOpacityTransition = transitionTest; @@ -148,7 +148,7 @@ @"backgroundPattern should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'Background Pattern'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.backgroundPattern = functionExpression; mbgl::style::IntervalStops<std::string> intervalStops = {{ @@ -172,8 +172,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.backgroundPattern = functionExpression, NSException, NSInvalidArgumentException, @"MGLBackgroundLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.backgroundPattern = functionExpression, NSException, NSInvalidArgumentException, @"MGLBackgroundLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.backgroundPatternTransition = transitionTest; diff --git a/platform/darwin/test/MGLCircleStyleLayerTests.mm b/platform/darwin/test/MGLCircleStyleLayerTests.mm index 7677344580..d7bf2a5afd 100644 --- a/platform/darwin/test/MGLCircleStyleLayerTests.mm +++ b/platform/darwin/test/MGLCircleStyleLayerTests.mm @@ -30,8 +30,8 @@ XCTAssertNil(layer.sourceLayerIdentifier); XCTAssertNil(layer.predicate); - layer.predicate = [NSPredicate predicateWithValue:NO]; - XCTAssertEqualObjects(layer.predicate, [NSPredicate predicateWithValue:NO]); + layer.predicate = [NSPredicate predicateWithFormat:@"$featureIdentifier = 1"]; + XCTAssertEqualObjects(layer.predicate, [NSPredicate predicateWithFormat:@"$featureIdentifier = 1"]); layer.predicate = nil; XCTAssertNil(layer.predicate); } @@ -63,7 +63,7 @@ @"circleBlur should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.circleBlur = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -77,7 +77,7 @@ XCTAssertEqualObjects(layer.circleBlur, functionExpression, @"circleBlur should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.circleBlur = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -85,10 +85,11 @@ XCTAssertEqual(rawLayer->getCircleBlur(), propertyValue, @"Setting circleBlur to a data expression should update circle-blur."); - XCTAssertEqualObjects(layer.circleBlur, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.circleBlur, pedanticFunctionExpression, @"circleBlur should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.circleBlur = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -98,7 +99,8 @@ XCTAssertEqual(rawLayer->getCircleBlur(), propertyValue, @"Setting circleBlur to a camera-data expression should update circle-blur."); - XCTAssertEqualObjects(layer.circleBlur, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.circleBlur, pedanticFunctionExpression, @"circleBlur should round-trip camera-data expressions."); @@ -133,7 +135,7 @@ @"circleColor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"%@", [MGLColor redColor]]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.circleColor = functionExpression; mbgl::style::IntervalStops<mbgl::Color> intervalStops = {{ @@ -147,7 +149,7 @@ XCTAssertEqualObjects(layer.circleColor, functionExpression, @"circleColor should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.circleColor = functionExpression; mbgl::style::ExponentialStops<mbgl::Color> exponentialStops = { {{18, { 1, 0, 0, 1 }}}, 1.0 }; @@ -155,10 +157,11 @@ XCTAssertEqual(rawLayer->getCircleColor(), propertyValue, @"Setting circleColor to a data expression should update circle-color."); - XCTAssertEqualObjects(layer.circleColor, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.circleColor, pedanticFunctionExpression, @"circleColor should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.circleColor = functionExpression; std::map<float, mbgl::Color> innerStops { {18, { 1, 0, 0, 1 }} }; @@ -168,7 +171,8 @@ XCTAssertEqual(rawLayer->getCircleColor(), propertyValue, @"Setting circleColor to a camera-data expression should update circle-color."); - XCTAssertEqualObjects(layer.circleColor, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.circleColor, pedanticFunctionExpression, @"circleColor should round-trip camera-data expressions."); @@ -203,7 +207,7 @@ @"circleOpacity should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.circleOpacity = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -217,7 +221,7 @@ XCTAssertEqualObjects(layer.circleOpacity, functionExpression, @"circleOpacity should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.circleOpacity = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -225,10 +229,11 @@ XCTAssertEqual(rawLayer->getCircleOpacity(), propertyValue, @"Setting circleOpacity to a data expression should update circle-opacity."); - XCTAssertEqualObjects(layer.circleOpacity, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.circleOpacity, pedanticFunctionExpression, @"circleOpacity should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.circleOpacity = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -238,7 +243,8 @@ XCTAssertEqual(rawLayer->getCircleOpacity(), propertyValue, @"Setting circleOpacity to a camera-data expression should update circle-opacity."); - XCTAssertEqualObjects(layer.circleOpacity, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.circleOpacity, pedanticFunctionExpression, @"circleOpacity should round-trip camera-data expressions."); @@ -273,7 +279,7 @@ @"circlePitchAlignment should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'viewport'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.circlePitchAlignment = functionExpression; mbgl::style::IntervalStops<mbgl::style::AlignmentType> intervalStops = {{ @@ -297,8 +303,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.circlePitchAlignment = functionExpression, NSException, NSInvalidArgumentException, @"MGLCircleLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.circlePitchAlignment = functionExpression, NSException, NSInvalidArgumentException, @"MGLCircleLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -317,7 +323,7 @@ @"circleRadius should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.circleRadius = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -331,7 +337,7 @@ XCTAssertEqualObjects(layer.circleRadius, functionExpression, @"circleRadius should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.circleRadius = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -339,10 +345,11 @@ XCTAssertEqual(rawLayer->getCircleRadius(), propertyValue, @"Setting circleRadius to a data expression should update circle-radius."); - XCTAssertEqualObjects(layer.circleRadius, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.circleRadius, pedanticFunctionExpression, @"circleRadius should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.circleRadius = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -352,7 +359,8 @@ XCTAssertEqual(rawLayer->getCircleRadius(), propertyValue, @"Setting circleRadius to a camera-data expression should update circle-radius."); - XCTAssertEqualObjects(layer.circleRadius, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.circleRadius, pedanticFunctionExpression, @"circleRadius should round-trip camera-data expressions."); @@ -387,7 +395,7 @@ @"circleScaleAlignment should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'viewport'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.circleScaleAlignment = functionExpression; mbgl::style::IntervalStops<mbgl::style::CirclePitchScaleType> intervalStops = {{ @@ -411,8 +419,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.circleScaleAlignment = functionExpression, NSException, NSInvalidArgumentException, @"MGLCircleLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.circleScaleAlignment = functionExpression, NSException, NSInvalidArgumentException, @"MGLCircleLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -431,7 +439,7 @@ @"circleStrokeColor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"%@", [MGLColor redColor]]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.circleStrokeColor = functionExpression; mbgl::style::IntervalStops<mbgl::Color> intervalStops = {{ @@ -445,7 +453,7 @@ XCTAssertEqualObjects(layer.circleStrokeColor, functionExpression, @"circleStrokeColor should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.circleStrokeColor = functionExpression; mbgl::style::ExponentialStops<mbgl::Color> exponentialStops = { {{18, { 1, 0, 0, 1 }}}, 1.0 }; @@ -453,10 +461,11 @@ XCTAssertEqual(rawLayer->getCircleStrokeColor(), propertyValue, @"Setting circleStrokeColor to a data expression should update circle-stroke-color."); - XCTAssertEqualObjects(layer.circleStrokeColor, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.circleStrokeColor, pedanticFunctionExpression, @"circleStrokeColor should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.circleStrokeColor = functionExpression; std::map<float, mbgl::Color> innerStops { {18, { 1, 0, 0, 1 }} }; @@ -466,7 +475,8 @@ XCTAssertEqual(rawLayer->getCircleStrokeColor(), propertyValue, @"Setting circleStrokeColor to a camera-data expression should update circle-stroke-color."); - XCTAssertEqualObjects(layer.circleStrokeColor, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.circleStrokeColor, pedanticFunctionExpression, @"circleStrokeColor should round-trip camera-data expressions."); @@ -501,7 +511,7 @@ @"circleStrokeOpacity should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.circleStrokeOpacity = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -515,7 +525,7 @@ XCTAssertEqualObjects(layer.circleStrokeOpacity, functionExpression, @"circleStrokeOpacity should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.circleStrokeOpacity = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -523,10 +533,11 @@ XCTAssertEqual(rawLayer->getCircleStrokeOpacity(), propertyValue, @"Setting circleStrokeOpacity to a data expression should update circle-stroke-opacity."); - XCTAssertEqualObjects(layer.circleStrokeOpacity, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.circleStrokeOpacity, pedanticFunctionExpression, @"circleStrokeOpacity should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.circleStrokeOpacity = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -536,7 +547,8 @@ XCTAssertEqual(rawLayer->getCircleStrokeOpacity(), propertyValue, @"Setting circleStrokeOpacity to a camera-data expression should update circle-stroke-opacity."); - XCTAssertEqualObjects(layer.circleStrokeOpacity, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.circleStrokeOpacity, pedanticFunctionExpression, @"circleStrokeOpacity should round-trip camera-data expressions."); @@ -571,7 +583,7 @@ @"circleStrokeWidth should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.circleStrokeWidth = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -585,7 +597,7 @@ XCTAssertEqualObjects(layer.circleStrokeWidth, functionExpression, @"circleStrokeWidth should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.circleStrokeWidth = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -593,10 +605,11 @@ XCTAssertEqual(rawLayer->getCircleStrokeWidth(), propertyValue, @"Setting circleStrokeWidth to a data expression should update circle-stroke-width."); - XCTAssertEqualObjects(layer.circleStrokeWidth, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.circleStrokeWidth, pedanticFunctionExpression, @"circleStrokeWidth should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.circleStrokeWidth = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -606,7 +619,8 @@ XCTAssertEqual(rawLayer->getCircleStrokeWidth(), propertyValue, @"Setting circleStrokeWidth to a camera-data expression should update circle-stroke-width."); - XCTAssertEqualObjects(layer.circleStrokeWidth, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.circleStrokeWidth, pedanticFunctionExpression, @"circleStrokeWidth should round-trip camera-data expressions."); @@ -647,7 +661,7 @@ @"circleTranslation should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"{1, 1}"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.circleTranslation = functionExpression; mbgl::style::IntervalStops<std::array<float, 2>> intervalStops = {{ @@ -671,8 +685,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.circleTranslation = functionExpression, NSException, NSInvalidArgumentException, @"MGLCircleLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.circleTranslation = functionExpression, NSException, NSInvalidArgumentException, @"MGLCircleLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -691,7 +705,7 @@ @"circleTranslationAnchor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'viewport'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.circleTranslationAnchor = functionExpression; mbgl::style::IntervalStops<mbgl::style::TranslateAnchorType> intervalStops = {{ @@ -715,8 +729,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.circleTranslationAnchor = functionExpression, NSException, NSInvalidArgumentException, @"MGLCircleLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.circleTranslationAnchor = functionExpression, NSException, NSInvalidArgumentException, @"MGLCircleLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } } diff --git a/platform/darwin/test/MGLDocumentationExampleTests.swift b/platform/darwin/test/MGLDocumentationExampleTests.swift index a216d9ad1c..9edb33a078 100644 --- a/platform/darwin/test/MGLDocumentationExampleTests.swift +++ b/platform/darwin/test/MGLDocumentationExampleTests.swift @@ -73,14 +73,14 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate { XCTAssertNotNil(mapView.style?.source(withIdentifier: "lines")) } - func testMGLRasterSource() { + func testMGLRasterTileSource() { //#-example-code - let source = MGLRasterSource(identifier: "clouds", tileURLTemplates: ["https://example.com/raster-tiles/{z}/{x}/{y}.png"], options: [ + let source = MGLRasterTileSource(identifier: "clouds", tileURLTemplates: ["https://example.com/raster-tiles/{z}/{x}/{y}.png"], options: [ .minimumZoomLevel: 9, .maximumZoomLevel: 16, .tileSize: 512, .attributionInfos: [ - MGLAttributionInfo(title: NSAttributedString(string: "© Mapbox"), url: URL(string: "http://mapbox.com")) + MGLAttributionInfo(title: NSAttributedString(string: "© Mapbox"), url: URL(string: "https://mapbox.com")) ] ]) mapView.style?.addSource(source) @@ -109,13 +109,13 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate { XCTAssertNotNil(mapView.style?.source(withIdentifier: "hills")) } - func testMGLVectorSource() { + func testMGLVectorTileSource() { //#-example-code - let source = MGLVectorSource(identifier: "pois", tileURLTemplates: ["https://example.com/vector-tiles/{z}/{x}/{y}.mvt"], options: [ + let source = MGLVectorTileSource(identifier: "pois", tileURLTemplates: ["https://example.com/vector-tiles/{z}/{x}/{y}.mvt"], options: [ .minimumZoomLevel: 9, .maximumZoomLevel: 16, .attributionInfos: [ - MGLAttributionInfo(title: NSAttributedString(string: "© Mapbox"), url: URL(string: "http://mapbox.com")) + MGLAttributionInfo(title: NSAttributedString(string: "© Mapbox"), url: URL(string: "https://mapbox.com")) ] ]) mapView.style?.addSource(source) @@ -151,7 +151,7 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate { } func testMGLCircleStyleLayer() { - let population = MGLVectorSource(identifier: "population", configurationURL: URL(string: "https://example.com/style.json")!) + let population = MGLVectorTileSource(identifier: "population", configurationURL: URL(string: "https://example.com/style.json")!) mapView.style?.addSource(population) //#-example-code @@ -162,7 +162,7 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate { #else layer.circleColor = NSExpression(forConstantValue: UIColor.green) #endif - layer.circleRadius = NSExpression(format: "FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'exponential', 1.75, %@)", + layer.circleRadius = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'exponential', 1.75, %@)", [12: 2, 22: 180]) layer.circleOpacity = NSExpression(forConstantValue: 0.7) @@ -174,13 +174,13 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate { } func testMGLLineStyleLayer() { - let trails = MGLVectorSource(identifier: "trails", configurationURL: URL(string: "https://example.com/style.json")!) + let trails = MGLVectorTileSource(identifier: "trails", configurationURL: URL(string: "https://example.com/style.json")!) mapView.style?.addSource(trails) //#-example-code let layer = MGLLineStyleLayer(identifier: "trails-path", source: trails) layer.sourceLayerIdentifier = "trails" - layer.lineWidth = NSExpression(format: "FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'exponential', 1.5, %@)", + layer.lineWidth = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'exponential', 1.5, %@)", [14: 2, 18: 20]) #if os(macOS) @@ -197,7 +197,7 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate { } func testMGLFillStyleLayer() { - let parks = MGLVectorSource(identifier: "parks", configurationURL: URL(string: "https://example.com/style.json")!) + let parks = MGLVectorTileSource(identifier: "parks", configurationURL: URL(string: "https://example.com/style.json")!) mapView.style?.addSource(parks) //#-example-code @@ -216,7 +216,7 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate { } func testMGLFillExtrusionStyleLayer() { - let buildings = MGLVectorSource(identifier: "buildings", configurationURL: URL(string: "https://example.com/style.json")!) + let buildings = MGLVectorTileSource(identifier: "buildings", configurationURL: URL(string: "https://example.com/style.json")!) mapView.style?.addSource(buildings) //#-example-code @@ -237,10 +237,10 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate { //#-example-code let layer = MGLHeatmapStyleLayer(identifier: "earthquake-heat", source: earthquakes) - layer.heatmapWeight = NSExpression(format: "FUNCTION(magnitude, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", + layer.heatmapWeight = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:(magnitude, 'linear', nil, %@)", [0: 0, 6: 1]) - layer.heatmapIntensity = NSExpression(format: "FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", + layer.heatmapIntensity = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", [0: 1, 9: 3]) mapView.style?.addLayer(layer) @@ -250,7 +250,7 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate { } func testMGLSymbolStyleLayer() { - let pois = MGLVectorSource(identifier: "pois", configurationURL: URL(string: "https://example.com/style.json")!) + let pois = MGLVectorTileSource(identifier: "pois", configurationURL: URL(string: "https://example.com/style.json")!) mapView.style?.addSource(pois) //#-example-code @@ -275,12 +275,12 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate { } func testMGLRasterStyleLayer() { - let source = MGLRasterSource(identifier: "clouds", tileURLTemplates: ["https://example.com/raster-tiles/{z}/{x}/{y}.png"], options: [ + let source = MGLRasterTileSource(identifier: "clouds", tileURLTemplates: ["https://example.com/raster-tiles/{z}/{x}/{y}.png"], options: [ .minimumZoomLevel: 9, .maximumZoomLevel: 16, .tileSize: 512, .attributionInfos: [ - MGLAttributionInfo(title: NSAttributedString(string: "© Mapbox"), url: URL(string: "http://mapbox.com")) + MGLAttributionInfo(title: NSAttributedString(string: "© Mapbox"), url: URL(string: "https://mapbox.com")) ] ]) mapView.style?.addSource(source) @@ -300,12 +300,12 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate { .maximumZoomLevel: 16, .tileSize: 256, .attributionInfos: [ - MGLAttributionInfo(title: NSAttributedString(string: "© Mapbox"), url: URL(string: "http://mapbox.com")) + MGLAttributionInfo(title: NSAttributedString(string: "© Mapbox"), url: URL(string: "https://mapbox.com")) ] ]) mapView.style?.addSource(source) - let canals = MGLVectorSource(identifier: "canals", configurationURL: URL(string: "https://example.com/style.json")!) + let canals = MGLVectorTileSource(identifier: "canals", configurationURL: URL(string: "https://example.com/style.json")!) mapView.style?.addSource(canals) let canalShadowLayer = MGLLineStyleLayer(identifier: "waterway-river-canal-shadow", source: canals) mapView.style?.addLayer(canalShadowLayer) @@ -322,13 +322,13 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate { } func testMGLVectorStyleLayer$predicate() { - let terrain = MGLVectorSource(identifier: "terrain", configurationURL: URL(string: "https://example.com/style.json")!) + let terrain = MGLVectorTileSource(identifier: "terrain", configurationURL: URL(string: "https://example.com/style.json")!) mapView.style?.addSource(terrain) //#-example-code let layer = MGLLineStyleLayer(identifier: "contour", source: terrain) layer.sourceLayerIdentifier = "contours" - layer.predicate = NSPredicate(format: "(index == 5 || index == 10) && ele >= 1500.0") + layer.predicate = NSPredicate(format: "(index == 5 || index == 10) && CAST(ele, 'NSNumber') >= 1500.0") mapView.style?.addLayer(layer) //#-end-example-code @@ -370,7 +370,7 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate { #endif class MGLStyle { - static func satelliteStreetsStyleURL() -> URL { + static var satelliteStreetsStyleURL: URL { return MGLDocumentationExampleTests.styleURL } } @@ -378,7 +378,7 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate { //#-example-code let camera = MGLMapCamera(lookingAtCenter: CLLocationCoordinate2D(latitude: 37.7184, longitude: -122.4365), fromDistance: 100, pitch: 20, heading: 0) - let options = MGLMapSnapshotOptions(styleURL: MGLStyle.satelliteStreetsStyleURL(), camera: camera, size: CGSize(width: 320, height: 480)) + let options = MGLMapSnapshotOptions(styleURL: MGLStyle.satelliteStreetsStyleURL, camera: camera, size: CGSize(width: 320, height: 480)) options.zoomLevel = 10 let snapshotter = MGLMapSnapshotter(options: options) diff --git a/platform/darwin/test/MGLDocumentationGuideTests.swift b/platform/darwin/test/MGLDocumentationGuideTests.swift index f939695f32..4de1d81aa9 100644 --- a/platform/darwin/test/MGLDocumentationGuideTests.swift +++ b/platform/darwin/test/MGLDocumentationGuideTests.swift @@ -50,10 +50,10 @@ class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate { styleLoadingExpectation.fulfill() } - func testUsingStyleFunctionsAtRuntime$Stops() { + func testMigratingToExpressions$Stops() { //#-example-code #if os(macOS) - let stops: [Float: NSColor] = [ + let stops: [NSNumber: NSColor] = [ 0: .yellow, 2.5: .orange, 5: .red, @@ -61,7 +61,7 @@ class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate { 10: .white, ] #else - let stops: [Float: UIColor] = [ + let stops: [NSNumber: UIColor] = [ 0: .yellow, 2.5: .orange, 5: .red, @@ -71,11 +71,11 @@ class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate { #endif //#-end-example-code - let _ = NSExpression(format: "FUNCTION(mag, 'mgl_stepWithMinimum:stops:', %@, %@)", + let _ = NSExpression(format: "mgl_step:from:stops:(mag, %@, %@)", stops[0]!, stops) } - func testUsingStyleFunctionsAtRuntime$Linear() { + func testMigratingToExpressions$Linear() { //#-example-code let url = URL(string: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson")! let symbolSource = MGLSource(identifier: "source") @@ -85,7 +85,7 @@ class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate { mapView.style?.addSource(source) #if os(macOS) - let stops: [Float: NSColor] = [ + let stops: [NSNumber: NSColor] = [ 0: .yellow, 2.5: .orange, 5: .red, @@ -93,7 +93,7 @@ class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate { 10: .white, ] #else - let stops: [Float: UIColor] = [ + let stops: [NSNumber: UIColor] = [ 0: .yellow, 2.5: .orange, 5: .red, @@ -104,10 +104,10 @@ class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate { let layer = MGLCircleStyleLayer(identifier: "circles", source: source) #if os(macOS) - layer.circleColor = NSExpression(format: "FUNCTION(mag, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", + layer.circleColor = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:(mag, 'linear', nil, %@)", stops) #else - layer.circleColor = NSExpression(format: "FUNCTION(mag, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", + layer.circleColor = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:(mag, 'linear', nil, %@)", stops) #endif layer.circleRadius = NSExpression(forConstantValue: 10) @@ -115,7 +115,37 @@ class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate { //#-end-example-code } - func testUsingStyleFunctionsAtRuntime$Exponential() { + func testMigratingToExpressions$LinearConvenience() { + let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil) + let layer = MGLCircleStyleLayer(identifier: "circles", source: source) + + #if os(macOS) + let stops: [NSNumber: NSColor] = [ + 0: .yellow, + 2.5: .orange, + 5: .red, + 7.5: .blue, + 10: .white, + ] + #else + let stops: [NSNumber: UIColor] = [ + 0: .yellow, + 2.5: .orange, + 5: .red, + 7.5: .blue, + 10: .white, + ] + #endif + + //#-example-code + layer.circleColor = NSExpression(forMGLInterpolating: NSExpression(forKeyPath: "mag"), curveType: .linear, parameters: nil, stops: NSExpression(forConstantValue: stops)) + //#-end-example-code + + layer.circleRadius = NSExpression(forConstantValue: 10) + mapView.style?.addLayer(layer) + + } + func testMigratingToExpressions$Exponential() { let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil) let layer = MGLCircleStyleLayer(identifier: "circles", source: source) @@ -126,18 +156,32 @@ class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate { 18: 18, ] - layer.circleRadius = NSExpression(format: "FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'exponential', 1.5, %@)", + layer.circleRadius = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'exponential', 1.5, %@)", stops) //#-end-example-code } - func testUsingStyleFunctionsAtRuntime$Interval() { + func testMigratingToExpressions$ExponentialConvenience() { + let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil) + let layer = MGLCircleStyleLayer(identifier: "circles", source: source) + + //#-example-code + let stops = [ + 12: 0.5, + 14: 2, + 18: 18, + ] + + layer.circleRadius = NSExpression(forMGLInterpolating: NSExpression.zoomLevelVariable, curveType: MGLExpressionInterpolationMode.exponential, parameters: NSExpression(forConstantValue: 1.5), stops: NSExpression(forConstantValue: stops)) + //#-end-example-code + } + func testMigratingToExpressions$Interval() { let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil) let layer = MGLCircleStyleLayer(identifier: "circles", source: source) //#-example-code #if os(macOS) - let stops: [Float: NSColor] = [ + let stops: [NSNumber: NSColor] = [ 0: .yellow, 2.5: .orange, 5: .red, @@ -145,10 +189,10 @@ class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate { 10: .white, ] - layer.circleColor = NSExpression(format: "FUNCTION(mag, 'mgl_stepWithMinimum:stops:', %@, %@)", + layer.circleColor = NSExpression(format: "mgl_step:from:stops:(mag, %@, %@)", NSColor.green, stops) #else - let stops: [Float: UIColor] = [ + let stops: [NSNumber: UIColor] = [ 0: .yellow, 2.5: .orange, 5: .red, @@ -156,40 +200,53 @@ class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate { 10: .white, ] - layer.circleColor = NSExpression(format: "FUNCTION(mag, 'mgl_stepWithMinimum:stops:', %@, %@)", + layer.circleColor = NSExpression(format: "mgl_step:from:stops:(mag, %@, %@)", UIColor.green, stops) #endif //#-end-example-code } - func testUsingStyleFunctionsAtRuntime$Categorical() { + func testMigratingToExpressions$Categorical() { let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil) let layer = MGLCircleStyleLayer(identifier: "circles", source: source) //#-example-code #if os(macOS) - let colors: [String: NSColor] = [ - "earthquake": .orange, - "explosion": .red, - "quarry blast": .yellow, - ] let defaultColor = NSColor.blue + layer.circleColor = NSExpression( + format: "MGL_MATCH(type, 'earthquake', %@, 'explosion', %@, 'quarry blast', %@, %@)", + NSColor.orange, NSColor.red, NSColor.yellow, defaultColor) #else - let colors: [String: UIColor] = [ - "earthquake": .orange, - "explosion": .red, - "quarry blast": .yellow, - ] let defaultColor = UIColor.blue + layer.circleColor = NSExpression(format: "MGL_MATCH(type, 'earthquake', %@, 'explosion', %@, 'quarry blast', %@, %@)", + UIColor.orange, UIColor.red, UIColor.yellow, defaultColor) #endif + //#-end-example-code + } + + func testMigratingToExpressions$CategoricalValue() { + let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil) + let layer = MGLCircleStyleLayer(identifier: "circles", source: source) + //#-example-code + #if os(macOS) + let stops : [String : NSColor] = ["earthquake" : NSColor.orange, + "explosion" : NSColor.red, + "quarry blast" : NSColor.yellow] + layer.circleColor = NSExpression( + format: "FUNCTION(%@, 'valueForKeyPath:', type)", + stops) + #else + let stops : [String : UIColor] = ["earthquake" : UIColor.orange, + "explosion" : UIColor.red, + "quarry blast" : UIColor.yellow] layer.circleColor = NSExpression( - format: "TERNARY(FUNCTION(%@, 'valueForKeyPath:', type) != nil, FUNCTION(%@, 'valueForKeyPath:', type), %@)", - colors, colors, defaultColor) + format: "FUNCTION(%@, 'valueForKeyPath:', type)", + stops) + #endif //#-end-example-code } - - func testUsingStyleFunctionsAtRuntime$Identity() { + func testMigratingToExpressions$Identity() { let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil) let layer = MGLCircleStyleLayer(identifier: "circles", source: source) @@ -197,4 +254,23 @@ class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate { layer.circleRadius = NSExpression(forKeyPath: "mag") //#-end-example-code } + + func testMigratingToExpressions$Multiply() { + let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil) + let layer = MGLCircleStyleLayer(identifier: "circles", source: source) + + //#-example-code + layer.circleRadius = NSExpression(forFunction: "multiply:by:", arguments: [NSExpression(forKeyPath: "mag"), 3]) + //#-end-example-code + } + + func testMigratingToExpressions$Cast() { + let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil) + + //#-example-code + let magnitudeLayer = MGLSymbolStyleLayer(identifier: "mag-layer", source: source) + magnitudeLayer.text = NSExpression(format: "CAST(mag, 'NSString')") + mapView.style?.addLayer(magnitudeLayer) + //#-end-example-code + } } diff --git a/platform/darwin/test/MGLExpressionTests.mm b/platform/darwin/test/MGLExpressionTests.mm index a5ed2f7bf5..d54e961b00 100644 --- a/platform/darwin/test/MGLExpressionTests.mm +++ b/platform/darwin/test/MGLExpressionTests.mm @@ -158,7 +158,7 @@ using namespace std::string_literals; NSExpression *expression = [NSExpression expressionForVariable:@"zoomLevel"]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, @[@"zoom"]); XCTAssertEqualObjects([NSExpression expressionWithFormat:@"$zoomLevel"].mgl_jsonExpressionObject, @[@"zoom"]); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:@[@"zoom"]], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:@[@"zoom"]], expression); NSMutableDictionary *context = [@{@"zoomLevel": @16} mutableCopy]; XCTAssertEqualObjects([expression expressionValueWithObject:nil context:context], @16); } @@ -166,25 +166,45 @@ using namespace std::string_literals; NSExpression *expression = [NSExpression expressionForVariable:@"heatmapDensity"]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, @[@"heatmap-density"]); XCTAssertEqualObjects([NSExpression expressionWithFormat:@"$heatmapDensity"].mgl_jsonExpressionObject, @[@"heatmap-density"]); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:@[@"heatmap-density"]], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:@[@"heatmap-density"]], expression); NSMutableDictionary *context = [@{@"heatmapDensity": @1} mutableCopy]; XCTAssertEqualObjects([expression expressionValueWithObject:nil context:context], @1); } { + NSExpression *expression = [NSExpression expressionForVariable:@"geometryType"]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, @[@"geometry-type"]); + XCTAssertEqualObjects([NSExpression expressionWithFormat:@"$geometryType"].mgl_jsonExpressionObject, @[@"geometry-type"]); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:@[@"geometry-type"]], expression); + } + { + NSExpression *expression = [NSExpression expressionForVariable:@"featureIdentifier"]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, @[@"id"]); + XCTAssertEqualObjects([NSExpression expressionWithFormat:@"$featureIdentifier"].mgl_jsonExpressionObject, @[@"id"]); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:@[@"id"]], expression); + } + { + NSExpression *expression = [NSExpression expressionForVariable:@"featureAttributes"]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, @[@"properties"]); + XCTAssertEqualObjects([NSExpression expressionWithFormat:@"$featureAttributes"].mgl_jsonExpressionObject, @[@"properties"]); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:@[@"properties"]], expression); + } + { NSExpression *expression = [NSExpression expressionForVariable:@"loremIpsum"]; NSArray *jsonExpression = @[@"var", @"loremIpsum"]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([NSExpression expressionWithFormat:@"$loremIpsum"].mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); NSMutableDictionary *context = [@{@"loremIpsum": @"Lorem ipsum dolor sit amet"} mutableCopy]; XCTAssertEqualObjects([expression expressionValueWithObject:nil context:context], @"Lorem ipsum dolor sit amet"); } { NSDictionary *context = @{@"loremIpsum": MGLConstantExpression(@"Lorem ipsum dolor sit amet")}; - NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(uppercase($loremIpsum), 'mgl_expressionWithContext:', %@)", context]; + NSExpression *expression = [NSExpression expressionWithFormat:@"MGL_LET('loremIpsum', 'Lorem ipsum dolor sit amet', uppercase($loremIpsum))", context]; + NSExpression *compatibilityExpression = [NSExpression expressionWithFormat:@"FUNCTION(uppercase($loremIpsum), 'mgl_expressionWithContext:', %@)", context]; NSArray *jsonExpression = @[@"let", @"loremIpsum", @"Lorem ipsum dolor sit amet", @[@"upcase", @[@"var", @"loremIpsum"]]]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects(compatibilityExpression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } } @@ -193,28 +213,28 @@ using namespace std::string_literals; NSExpression *expression = [NSExpression expressionForConstantValue:nil]; XCTAssert(expression.mgl_jsonExpressionObject == [NSNull null]); XCTAssert([NSExpression expressionWithFormat:@"nil"].mgl_jsonExpressionObject == [NSNull null]); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:[NSNull null]], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:[NSNull null]], expression); XCTAssertNil([expression expressionValueWithObject:nil context:nil]); } { NSExpression *expression = [NSExpression expressionForConstantValue:@1]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, @1); XCTAssertEqualObjects([NSExpression expressionWithFormat:@"1"].mgl_jsonExpressionObject, @1); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:@1], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:@1], expression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @1); } { NSExpression *expression = [NSExpression expressionForConstantValue:@YES]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, @YES); XCTAssertEqualObjects([NSExpression expressionWithFormat:@"TRUE"].mgl_jsonExpressionObject, @YES); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:@YES], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:@YES], expression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @YES); } { NSExpression *expression = [NSExpression expressionForConstantValue:nil]; XCTAssert(expression.mgl_jsonExpressionObject == [NSNull null]); XCTAssert([NSExpression expressionWithFormat:@"nil"].mgl_jsonExpressionObject == [NSNull null]); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:[NSNull null]], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:[NSNull null]], expression); XCTAssertNil([expression expressionValueWithObject:nil context:nil]); } { @@ -227,7 +247,7 @@ using namespace std::string_literals; #endif XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); // No way to distinguish offsets from ordinary arrays in expressions. - XCTAssertEqualObjects([[NSExpression mgl_expressionWithJSONObject:jsonExpression].collection valueForKeyPath:@"constantValue"], jsonExpression.lastObject); + XCTAssertEqualObjects([[NSExpression expressionWithMGLJSONObject:jsonExpression].collection valueForKeyPath:@"constantValue"], jsonExpression.lastObject); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @(vector)); } { @@ -242,7 +262,7 @@ using namespace std::string_literals; NSArray *jsonExpression = @[@"literal", @[@1, @4, @3, @2]]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); // No way to distinguish offsets from ordinary arrays in expressions. - XCTAssertEqualObjects([[NSExpression mgl_expressionWithJSONObject:jsonExpression].collection valueForKeyPath:@"constantValue"], jsonExpression.lastObject); + XCTAssertEqualObjects([[NSExpression expressionWithMGLJSONObject:jsonExpression].collection valueForKeyPath:@"constantValue"], jsonExpression.lastObject); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], value); } { @@ -272,19 +292,19 @@ using namespace std::string_literals; NSArray *jsonExpression = @[@"get", @"highway"]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([NSExpression expressionWithFormat:@"highway"].mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSExpression *expression = [NSExpression expressionWithFormat:@"%@.population", @{@"population": MGLConstantExpression(@12000)}]; NSArray *jsonExpression = @[@"get", @"population", @[@"literal", @{@"population": @12000}]]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSExpression *expression = [NSExpression expressionWithFormat:@"%@.uppercase('population')", @{@"POPULATION": MGLConstantExpression(@12000)}]; NSArray *jsonExpression = @[@"get", @[@"upcase", @"population"], @[@"literal", @{@"POPULATION": @12000}]]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } } @@ -300,28 +320,28 @@ using namespace std::string_literals; NSArray *jsonExpression = @[@"+", @1, @2, @2, @3, @4, @7, @9]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @28); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSExpression *expression = [NSExpression expressionWithFormat:@"count({1, 2, 2, 3, 4, 7, 9})"]; NSArray *jsonExpression = @[@"length", @[@"literal", @[@1, @2, @2, @3, @4, @7, @9]]]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @7); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSExpression *expression = [NSExpression expressionWithFormat:@"min({1, 2, 2, 3, 4, 7, 9})"]; NSArray *jsonExpression = @[@"min", @1, @2, @2, @3, @4, @7, @9]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @1); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSExpression *expression = [NSExpression expressionWithFormat:@"max({1, 2, 2, 3, 4, 7, 9})"]; NSArray *jsonExpression = @[@"max", @1, @2, @2, @3, @4, @7, @9]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @9); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } } @@ -332,61 +352,66 @@ using namespace std::string_literals; NSArray *jsonExpression = @[@"+", @1, @1]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([NSExpression expressionWithFormat:@"1 + 1"].mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSArray *arguments = @[MGLConstantExpression(@1), MGLConstantExpression(@1), MGLConstantExpression(@1)]; + NSExpression *expression = [NSExpression expressionForFunction:@"add:to:" arguments:arguments]; + NSArray *jsonExpression = @[@"+", @1, @1, @1]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + jsonExpression = @[@"+", @[@"+", @1, @1], @1]; + XCTAssertEqualObjects([NSExpression expressionWithFormat:@"1 + 1 + 1"].mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], [NSExpression expressionWithFormat:@"1 + 1 + 1"]); } { NSExpression *expression = [NSExpression expressionForFunction:@"from:subtract:" arguments:arguments]; NSArray *jsonExpression = @[@"-", @1, @1]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([NSExpression expressionWithFormat:@"1 - 1"].mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSExpression *expression = [NSExpression expressionForFunction:@"multiply:by:" arguments:arguments]; NSArray *jsonExpression = @[@"*", @1, @1]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([NSExpression expressionWithFormat:@"1 * 1"].mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSExpression *expression = [NSExpression expressionForFunction:@"divide:by:" arguments:arguments]; NSArray *jsonExpression = @[@"/", @1, @1]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([NSExpression expressionWithFormat:@"1 / 1"].mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSExpression *expression = [NSExpression expressionForFunction:@"modulus:by:" arguments:arguments]; NSArray *jsonExpression = @[@"%", @1, @1]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); // NSExpression lacks a shorthand operator for modulus. - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSExpression *expression = [NSExpression expressionForFunction:@"ceiling:" arguments:@[MGLConstantExpression(@1.5)]]; - NSArray *jsonTruncation = @[@"-", @1.5, @[@"%", @1.5, @1]]; - NSArray *jsonExpression = @[@"+", jsonTruncation, @[@"case", @[@">", @[@"%", @1.5, @1], @0], @1, @0]]; + NSArray *jsonExpression = @[@"ceil", @1.5]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @2); } { NSExpression *expression = [NSExpression expressionForFunction:@"ceiling:" arguments:@[MGLConstantExpression(@-1.5)]]; - NSArray *jsonTruncation = @[@"-", @-1.5, @[@"%", @-1.5, @1]]; - NSArray *jsonExpression = @[@"+", jsonTruncation, @[@"case", @[@">", @[@"%", @-1.5, @1], @0], @1, @0]]; + NSArray *jsonExpression = @[@"ceil", @-1.5]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @-1); } { NSExpression *expression = [NSExpression expressionForFunction:@"ceiling:" arguments:@[MGLConstantExpression(@2)]]; - NSArray *jsonTruncation = @[@"-", @2, @[@"%", @2, @1]]; - NSArray *jsonExpression = @[@"+", jsonTruncation, @[@"case", @[@">", @[@"%", @2, @1], @0], @1, @0]]; + NSArray *jsonExpression = @[@"ceil", @2]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @2); } { NSExpression *expression = [NSExpression expressionForFunction:@"ceiling:" arguments:@[MGLConstantExpression(@-2)]]; - NSArray *jsonTruncation = @[@"-", @-2, @[@"%", @-2, @1]]; - NSArray *jsonExpression = @[@"+", jsonTruncation, @[@"case", @[@">", @[@"%", @-2, @1], @0], @1, @0]]; + NSArray *jsonExpression = @[@"ceil", @-2]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @-2); } @@ -404,44 +429,64 @@ using namespace std::string_literals; } { NSExpression *expression = [NSExpression expressionForFunction:@"abs:" arguments:@[MGLConstantExpression(@2)]]; - NSArray *jsonExpression = @[@"*", @2, @[@"case", @[@">", @2, @0], @1, @-1]]; + NSArray *jsonExpression = @[@"abs", @2]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @2); } { NSExpression *expression = [NSExpression expressionForFunction:@"abs:" arguments:@[MGLConstantExpression(@-2)]]; - NSArray *jsonExpression = @[@"*", @-2, @[@"case", @[@">", @-2, @0], @1, @-1]]; + NSArray *jsonExpression = @[@"abs", @-2]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @2); } { NSExpression *expression = [NSExpression expressionForFunction:@"floor:" arguments:@[MGLConstantExpression(@1.5)]]; - NSArray *jsonTruncation = @[@"-", @1.5, @[@"%", @1.5, @1]]; - NSArray *jsonExpression = @[@"-", jsonTruncation, @[@"case", @[@"<", @[@"%", @1.5, @1], @0], @1, @0]]; + NSArray *jsonExpression = @[@"floor", @1.5]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @1); } { NSExpression *expression = [NSExpression expressionForFunction:@"floor:" arguments:@[MGLConstantExpression(@-1.5)]]; - NSArray *jsonTruncation = @[@"-", @-1.5, @[@"%", @-1.5, @1]]; - NSArray *jsonExpression = @[@"-", jsonTruncation, @[@"case", @[@"<", @[@"%", @-1.5, @1], @0], @1, @0]]; + NSArray *jsonExpression = @[@"floor", @-1.5]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @-2); } { NSExpression *expression = [NSExpression expressionForFunction:@"floor:" arguments:@[MGLConstantExpression(@2)]]; - NSArray *jsonTruncation = @[@"-", @2, @[@"%", @2, @1]]; - NSArray *jsonExpression = @[@"-", jsonTruncation, @[@"case", @[@"<", @[@"%", @2, @1], @0], @1, @0]]; + NSArray *jsonExpression = @[@"floor", @2]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @2); } { NSExpression *expression = [NSExpression expressionForFunction:@"floor:" arguments:@[MGLConstantExpression(@-2)]]; - NSArray *jsonTruncation = @[@"-", @-2, @[@"%", @-2, @1]]; - NSArray *jsonExpression = @[@"-", jsonTruncation, @[@"case", @[@"<", @[@"%", @-2, @1], @0], @1, @0]]; + NSArray *jsonExpression = @[@"floor", @-2]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @-2); } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_round:" arguments:@[MGLConstantExpression(@1.5)]]; + NSArray *jsonExpression = @[@"round", @1.5]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @2); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_round:" arguments:@[MGLConstantExpression(@-1.5)]]; + NSArray *jsonExpression = @[@"round", @-1.5]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @-2); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_round:" arguments:@[MGLConstantExpression(@2.5)]]; + NSArray *jsonExpression = @[@"round", @2.5]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @3); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_round:" arguments:@[MGLConstantExpression(@-2.5)]]; + NSArray *jsonExpression = @[@"round", @-2.5]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @-3); + } } - (void)testTrigonometricExpressionObject { @@ -450,41 +495,91 @@ using namespace std::string_literals; NSExpression *expression = [NSExpression expressionForFunction:@"sqrt:" arguments:arguments]; NSArray *jsonExpression = @[@"sqrt", @1, @1]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSExpression *expression = [NSExpression expressionForFunction:@"ln:" arguments:arguments]; NSArray *jsonExpression = @[@"ln", @1, @1]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_log2:" arguments:@[MGLConstantExpression(@1024)]]; + NSArray *jsonExpression = @[@"log2", @1024]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @10); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSExpression *expression = [NSExpression expressionForFunction:@"raise:toPower:" arguments:arguments]; NSArray *jsonExpression = @[@"^", @1, @1]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([NSExpression expressionWithFormat:@"1 ** 1"].mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSExpression *expression = [NSExpression expressionForFunction:@"exp:" arguments:@[MGLConstantExpression(@0)]]; NSArray *jsonExpression = @[@"^", @[@"e"], @0]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @1); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSExpression *expression = [NSExpression expressionForConstantValue:@(M_E)]; NSArray *jsonExpression = @[@"e"]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @(M_E)); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSExpression *expression = [NSExpression expressionForConstantValue:@(M_PI)]; NSArray *jsonExpression = @[@"pi"]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @(M_PI)); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_acos:" arguments:@[MGLConstantExpression(@1)]]; + NSArray *jsonExpression = @[@"acos", @1]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @0); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_cos:" arguments:@[MGLConstantExpression(@0)]]; + NSArray *jsonExpression = @[@"cos", @0]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @1); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_asin:" arguments:@[MGLConstantExpression(@0)]]; + NSArray *jsonExpression = @[@"asin", @0]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @0); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_sin:" arguments:@[MGLConstantExpression(@0)]]; + NSArray *jsonExpression = @[@"sin", @0]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @0); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_atan:" arguments:@[MGLConstantExpression(@20)]]; + NSArray *jsonExpression = @[@"atan", @20]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + NSNumber *value = [expression expressionValueWithObject:nil context:nil]; + XCTAssertEqualWithAccuracy(value.doubleValue, 1.52, 0.001); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_tan:" arguments:@[MGLConstantExpression(@0)]]; + NSArray *jsonExpression = @[@"tan", @0]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @0); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } } @@ -492,22 +587,31 @@ using namespace std::string_literals; NSArray *arguments = @[MGLConstantExpression(@"MacDonald")]; { NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION('Old', 'stringByAppendingString:', 'MacDonald')"]; + NSExpression *aftermarketExpression = [NSExpression expressionWithFormat:@"mgl_join({'Old', 'MacDonald'})"]; NSArray *jsonExpression = @[@"concat", @"Old", @"MacDonald"]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects(aftermarketExpression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @"OldMacDonald"); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([aftermarketExpression expressionValueWithObject:nil context:nil], @"OldMacDonald"); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], aftermarketExpression); } { NSExpression *expression = [NSExpression expressionForFunction:@"uppercase:" arguments:arguments]; NSArray *jsonExpression = @[@"upcase", @"MacDonald"]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSExpression *expression = [NSExpression expressionForFunction:@"lowercase:" arguments:arguments]; NSArray *jsonExpression = @[@"downcase", @"MacDonald"]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"length:" arguments:arguments]; + NSArray *jsonExpression = @[@"length", @"MacDonald"]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } } @@ -518,7 +622,20 @@ using namespace std::string_literals; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); // NSExpression is unable to evaluate -[NSNumber boolValue] by itself // because it returns a primitive instead of an object. - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(postalCode, 'mgl_number')"]; + NSArray *jsonExpression = @[@"to-number", @[@"get", @"postalCode"]]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithFormat:@"FUNCTION(postalCode, 'doubleValue')"].mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithFormat:@"FUNCTION(postalCode, 'floatValue')"].mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithFormat:@"FUNCTION(postalCode, 'decimalValue')"].mgl_jsonExpressionObject, jsonExpression); + // NSExpression is unable to evaluate NSNumber’s -floatValue, + // -doubleValue, or -decimalValue by themselves because they each return + // a primitive instead of an object. + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], + [NSExpression expressionWithFormat:@"CAST(postalCode, 'NSNumber')"]); } { NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(postalCode, 'mgl_numberWithFallbackValues:', zipCode)"]; @@ -530,50 +647,117 @@ using namespace std::string_literals; // NSExpression is unable to evaluate NSNumber’s -floatValue, // -doubleValue, or -decimalValue by themselves because they each return // a primitive instead of an object. - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { - NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(number, 'stringValue')"]; + NSExpression *expression = [NSExpression expressionWithFormat:@"CAST(postalCode, 'NSNumber')"]; + NSExpression *compatibilityExpression = [NSExpression expressionWithFormat:@"FUNCTION(postalCode, 'mgl_numberWithFallbackValues:')"]; + NSArray *jsonExpression = @[@"to-number", @[@"get", @"postalCode"]]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects(compatibilityExpression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:@{@"postalCode": @"02134"} context:nil], @02134); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionWithFormat:@"CAST(number, 'NSString')"]; + NSExpression *compatibilityExpression = [NSExpression expressionWithFormat:@"FUNCTION(number, 'stringValue')"]; NSArray *jsonExpression = @[@"to-string", @[@"get", @"number"]]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects(compatibilityExpression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:@{@"number": @1.5} context:nil], @"1.5"); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([compatibilityExpression expressionValueWithObject:@{@"number": @1.5} context:nil], @"1.5"); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } } - (void)testInterpolationExpressionObject { { NSDictionary *stops = @{@0: MGLConstantExpression(@100), @10: MGLConstantExpression(@200)}; - NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(x, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", stops]; + NSExpression *expression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(x, 'linear', nil, %@)", stops]; + NSExpression *compatibilityExpression = [NSExpression expressionWithFormat:@"FUNCTION(x, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", stops]; NSArray *jsonExpression = @[@"interpolate", @[@"linear"], @[@"get", @"x"], @0, @100, @10, @200]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects(compatibilityExpression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSDictionary *stops = @{@1: MGLConstantExpression(@2), @3: MGLConstantExpression(@6)}; - NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(x, 'mgl_interpolateWithCurveType:parameters:stops:', 'exponential', 2, %@)", stops]; + NSExpression *expression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(x, 'exponential', 2, %@)", stops]; NSArray *jsonExpression = @[@"interpolate", @[@"exponential", @2], @[@"get", @"x"], @1, @2, @3, @6]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSDictionary *stops = @{@0: MGLConstantExpression(@0), @100: MGLConstantExpression(@100)}; - NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(x, 'mgl_interpolateWithCurveType:parameters:stops:', 'cubic-bezier', { 0.42, 0, 0.58, 1 }, %@)", stops]; + NSExpression *expression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(x, 'cubic-bezier', { 0.42, 0, 0.58, 1 }, %@)", stops]; NSArray *jsonExpression = @[@"interpolate", @[@"cubic-bezier", @0.42, @0, @0.58, @1], @[@"get", @"x"], @0, @0, @100, @100]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSDictionary *stops = @{@0: MGLConstantExpression(@111), @1: MGLConstantExpression(@1111)}; - NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(x, 'mgl_stepWithMinimum:stops:', 11, %@)", stops]; + NSExpression *expression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(x, 11, %@)", stops]; + NSExpression *compatibilityExpression = [NSExpression expressionWithFormat:@"FUNCTION(x, 'mgl_stepWithMinimum:stops:', 11, %@)", stops]; NSArray *jsonExpression = @[@"step", @[@"get", @"x"], @11, @0, @111, @1, @1111]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects(compatibilityExpression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSDictionary *stops = @{@0: MGLConstantExpression(@111), @1: MGLConstantExpression(@1111)}; + NSExpression *expression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, 11, %@)", stops]; + NSArray *jsonExpression = @[@"step", @[@"zoom"], @11, @0, @111, @1, @1111]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } } +- (void)testMatchExpressionObject { + { + NSExpression *expression = [NSExpression expressionWithFormat:@"MGL_MATCH(2 - 1, %@, %@, %@, %@, 'default')", MGLConstantExpression(@1), + MGLConstantExpression(@"one"), + MGLConstantExpression(@0), + MGLConstantExpression(@"zero")]; + NSExpression *predicate = [NSExpression expressionWithFormat:@"2 - 1"]; + NSExpression *compatibilityExpression = [NSExpression expressionWithFormat:@"FUNCTION(%@, 'mgl_match:', %@)", predicate, @[MGLConstantExpression(@1), + MGLConstantExpression(@"one"), + MGLConstantExpression(@0), + MGLConstantExpression(@"zero"), + MGLConstantExpression(@"default")]]; + NSArray *jsonExpression = @[@"match", @[@"-", @2, @1], @1, @"one", @0, @"zero", @"default"]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects(compatibilityExpression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionWithFormat:@"MGL_MATCH(2 * 1, %@, %@, 'default')", MGLConstantExpression(@1), MGLConstantExpression(@"one")]; + NSArray *jsonExpression = @[@"match", @[@"*", @2, @1], @1, @"one", @"default"]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } +} + +- (void)testCoalesceExpressionObject { + { + NSExpression *expression = [NSExpression expressionWithFormat:@"mgl_coalesce(%@)", + @[[NSExpression expressionForKeyPath:@"x"], + [NSExpression expressionForKeyPath:@"y"], + [NSExpression expressionForKeyPath:@"z"], + [NSExpression expressionForConstantValue:@0]]]; + NSExpression *compatibilityExpression = [NSExpression expressionWithFormat:@"FUNCTION(%@, 'mgl_coalesce')", @[[NSExpression expressionForKeyPath:@"x"], + [NSExpression expressionForKeyPath:@"y"], + [NSExpression expressionForKeyPath:@"z"], + [NSExpression expressionForConstantValue:@0]]]; + NSArray *jsonExpression = @[@"coalesce", @[@"get", @"x"], @[@"get", @"y"], @[@"get", @"z"], @0]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects(compatibilityExpression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + +} + - (void)testConditionalExpressionObject { - // FIXME: This test crashes because iOS 8 doesn't have `+[NSExpression expressionForConditional:trueExpression:falseExpression:]`. + // This test crashes on iOS 8, which doesn't have `+[NSExpression expressionForConditional:trueExpression:falseExpression:]`. // https://github.com/mapbox/mapbox-gl-native/issues/11007 if (@available(iOS 9.0, *)) { { @@ -585,16 +769,341 @@ using namespace std::string_literals; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([NSExpression expressionWithFormat:@"TERNARY(1 = 2, TRUE, FALSE)"].mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @NO); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); } { NSExpression *expression = [NSExpression expressionWithFormat:@"TERNARY(0 = 1, TRUE, TERNARY(1 = 2, TRUE, FALSE))"]; NSArray *jsonExpression = @[@"case", @[@"==", @0, @1], @YES, @[@"==", @1, @2], @YES, @NO]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @NO); - XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression); + expression = [NSExpression expressionWithFormat:@"MGL_IF(%@, TRUE, %@, TRUE, FALSE)", + MGLConstantExpression([NSPredicate predicateWithFormat:@"0 = 1"]), + MGLConstantExpression([NSPredicate predicateWithFormat:@"1 = 2"])]; + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + } + { + NSExpression *expression = [NSExpression expressionWithFormat:@"MGL_IF(%@, %@, %@)", + [NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 2"]], + MGLConstantExpression(@YES), + MGLConstantExpression(@NO)]; + NSExpression *compatibilityExpression = [NSExpression expressionWithFormat:@"FUNCTION(%@, 'mgl_if:', %@)", [NSPredicate predicateWithFormat:@"1 = 2"], @[MGLConstantExpression(@YES), MGLConstantExpression(@NO)]]; + NSArray *jsonExpression = @[@"case", @[@"==", @1, @2], @YES, @NO]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects(compatibilityExpression.mgl_jsonExpressionObject, jsonExpression); + if (@available(iOS 9.0, *)) { + expression = [NSExpression expressionWithFormat:@"TERNARY(1 = 2, YES, NO)"]; + } + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @NO); + } + { + NSExpression *expression = [NSExpression expressionWithFormat:@"MGL_IF(%@, %@, %@, %@, %@)", + [NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 2"]], + MGLConstantExpression(@YES), + [NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 1"]], + MGLConstantExpression(@YES), + MGLConstantExpression(@NO)]; + NSArray *jsonExpression = @[@"case", @[@"==", @1, @2], @YES, @[@"==", @1, @1], @YES, @NO]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @YES); + } + { + NSArray *jsonExpression = @[ + @"case", + @[ + @"<", + @[@"get", @"area"], + @80000 + ], + @[@"get", @"abbr"], + @[@"get", @"name_en"] + ]; + NSExpression *expression = [NSExpression expressionWithFormat:@"TERNARY(area < 80000, abbr, name_en)"]; + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + } +} + +- (void)testLookupExpressionObject { + { + NSExpression *array = [NSExpression expressionForAggregate:@[MGLConstantExpression(@9), + MGLConstantExpression(@8), + MGLConstantExpression(@7)]]; + NSExpression *expression = [NSExpression expressionForFunction:@"objectFrom:withIndex:" + arguments:@[array, MGLConstantExpression(@1)]]; + NSArray *jsonExpression = @[@"at", @1, @[ @"literal", @[@9, @8, @7]]]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *array = [NSExpression expressionForAggregate:@[MGLConstantExpression(@9), + MGLConstantExpression(@8), + MGLConstantExpression(@7)]]; + NSExpression *expression = [NSExpression expressionForFunction:@"objectFrom:withIndex:" + arguments:@[array, [NSExpression expressionForKeyPath:@"x"]]]; + NSArray *jsonExpression = @[@"at", @[@"get", @"x"], @[ @"literal", @[@9, @8, @7]]]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_does:have:" + arguments:@[[NSExpression expressionForEvaluatedObject], + [NSExpression expressionForConstantValue:@"x"]]]; + NSExpression *compatibilityExpression = [NSExpression expressionWithFormat:@"FUNCTION(self, 'mgl_has:', 'x')"]; + NSArray *jsonExpression = @[@"has", @"x"]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects(compatibilityExpression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_does:have:" + arguments:@[MGLConstantExpression(@{@"x": MGLConstantExpression(@0)}), + MGLConstantExpression(@"x")]]; + NSArray *jsonExpression = @[@"has", @"x", @[@"literal", @{@"x": @0}]]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [NSExpression expressionForFunction:@"mgl_does:have:" + arguments:@[[NSExpression expressionForVariable:@"featureAttributes"], + [NSExpression expressionForConstantValue:@"x"]]]; + NSArray *jsonExpression = @[@"has", @"x", @[@"properties"]]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression; + if (@available(iOS 9.0, *)) { + expression = [NSExpression expressionWithFormat:@"TERNARY(key != nil, 1, 0)"]; + } else { + expression = [NSExpression expressionWithFormat:@"MGL_IF(%@, 1, 0)", + MGLConstantExpression([NSPredicate predicateWithFormat:@"key != nil"])]; } + NSArray *jsonExpression = @[@"case", @[@"!=", @[@"get", @"key"], [NSNull null]], @1, @0]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([expression expressionValueWithObject:@{} context:nil], @NO); + XCTAssertEqualObjects([expression expressionValueWithObject:@{@"key": @"🗝"} context:nil], @YES); + } + { + NSDictionary *dictionary = @{@"key": @"🔑"}; + NSExpression *expression; + if (@available(iOS 9.0, *)) { + expression = [NSExpression expressionWithFormat:@"TERNARY(%@.key != nil, 1, 0)", dictionary]; + } else { + NSPredicate *conditional = [NSPredicate predicateWithFormat:@"%@.key != nil", dictionary]; + expression = [NSExpression expressionWithFormat:@"MGL_IF(%@, 1, 0)", + MGLConstantExpression(conditional)]; + } + NSArray *jsonExpression = @[@"case", @[@"!=", @[@"get", @"key", @[@"literal", dictionary]], [NSNull null]], @1, @0]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + // The dictionary isn’t equal enough. + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression].description, expression.description); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @YES); + } +} + +- (void)testGenericExpressionObject { + { + NSExpression *expression = [NSExpression expressionWithFormat:@"MGL_FUNCTION('random', 1, 2, 3, 4, 5)"]; + NSArray *jsonExpression = @[@"random", @1, @2, @3, @4, @5]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + expression = [NSExpression expressionWithFormat:@"MGL_FUNCTION('random', 1, 2, 3, 4)"]; + XCTAssertThrowsSpecificNamed([expression expressionValueWithObject:nil context:nil], NSException, NSInvalidArgumentException); + } +} + +#pragma mark - Localization tests + +- (void)testTokenReplacement { + { + NSExpression *original = MGLConstantExpression(@""); + NSExpression *expected = original; + XCTAssertEqualObjects(original.mgl_expressionByReplacingTokensWithKeyPaths, expected); + } + { + NSExpression *original = MGLConstantExpression(@"{"); + NSExpression *expected = original; + XCTAssertEqualObjects(original.mgl_expressionByReplacingTokensWithKeyPaths, expected); + } + { + NSExpression *original = MGLConstantExpression(@"{token"); + NSExpression *expected = original; + XCTAssertEqualObjects(original.mgl_expressionByReplacingTokensWithKeyPaths, expected); + } + { + NSExpression *original = MGLConstantExpression(@"{token}"); + NSExpression *expected = [NSExpression expressionForKeyPath:@"token"]; + XCTAssertEqualObjects(original.mgl_expressionByReplacingTokensWithKeyPaths, expected); + } + { + NSExpression *original = MGLConstantExpression(@"{token} {token}"); + NSExpression *expected = [NSExpression expressionWithFormat:@"mgl_join({token, ' ', token})"]; + XCTAssertEqualObjects(original.mgl_expressionByReplacingTokensWithKeyPaths, expected); + } + { + NSExpression *original = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, '{short}', %@)", @{ + @1: MGLConstantExpression(@"{short}"), + @2: @"…", + @3: @"{long}", + }]; + NSExpression *expected = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, short, %@)", @{ + @1: [NSExpression expressionForKeyPath:@"short"], + @2: @"…", + @3: [NSExpression expressionForKeyPath:@"long"], + }]; + XCTAssertEqualObjects(original.mgl_expressionByReplacingTokensWithKeyPaths, expected); + } +} + +- (void)testLocalization { + { + NSExpression *original = MGLConstantExpression(@""); + NSExpression *expected = original; + XCTAssertEqualObjects([original mgl_expressionLocalizedIntoLocale:nil], expected); + } + { + NSExpression *original = MGLConstantExpression(@"Old MacDonald"); + NSExpression *expected = original; + XCTAssertEqualObjects([original mgl_expressionLocalizedIntoLocale:nil], expected); + } + { + NSExpression *original = MGLConstantExpression(@"{name_en}"); + NSExpression *expected = original; + XCTAssertEqualObjects([original mgl_expressionLocalizedIntoLocale:nil], expected); + } + { + NSExpression *original = [NSExpression expressionForKeyPath:@"name_en"]; + NSExpression *expected = original; + XCTAssertEqualObjects([original mgl_expressionLocalizedIntoLocale:nil], expected); + } + { + NSExpression *original = [NSExpression expressionForKeyPath:@"name_en"]; + NSExpression *expected = [NSExpression expressionForKeyPath:@"name"]; + XCTAssertEqualObjects([original mgl_expressionLocalizedIntoLocale:[NSLocale localeWithLocaleIdentifier:@"mul"]], expected); + } + { + NSExpression *original = [NSExpression expressionForKeyPath:@"name_en"]; + NSExpression *expected = [NSExpression expressionForKeyPath:@"name_fr"]; + XCTAssertEqualObjects([original mgl_expressionLocalizedIntoLocale:[NSLocale localeWithLocaleIdentifier:@"fr-CA"]], expected); + } + { + NSExpression *original = [NSExpression expressionForKeyPath:@"name_en"]; + NSExpression *expected = [NSExpression expressionForKeyPath:@"name_zh-Hans"]; + XCTAssertEqualObjects([original mgl_expressionLocalizedIntoLocale:[NSLocale localeWithLocaleIdentifier:@"zh-Hans"]], expected); + } + { + NSExpression *original = [NSExpression expressionForKeyPath:@"name_en"]; + NSExpression *expected = [NSExpression expressionForKeyPath:@"name"]; + XCTAssertEqualObjects([original mgl_expressionLocalizedIntoLocale:[NSLocale localeWithLocaleIdentifier:@"tlh"]], expected); + } + { + NSExpression *original = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, short, %@)", @{ + @1: [NSExpression expressionForKeyPath:@"abbr"], + @2: @"…", + @3: [NSExpression expressionForKeyPath:@"name_fr"], + }]; + NSExpression *expected = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, short, %@)", @{ + @1: [NSExpression expressionForKeyPath:@"abbr"], + @2: @"…", + @3: [NSExpression expressionForKeyPath:@"name_es"], + }]; + XCTAssertEqualObjects([original mgl_expressionLocalizedIntoLocale:[NSLocale localeWithLocaleIdentifier:@"es-PR"]], expected); + } + { + NSArray *jsonExpression = @[ + @"step", + @[@"zoom"], + @[ + @"case", + @[ + @"<", + @[ + @"to-number", + @[@"get", @"area"] + ], + @80000 + ], + @[@"get", @"abbr"], + @[@"get", @"name_en"] + ], + @5, @[@"get", @"name_en"] + ]; + NSArray *localizedJSONExpression = @[ + @"step", + @[@"zoom"], + @[ + @"case", + @[ + @"<", + @[ + @"to-number", + @[@"get", @"area"] + ], + @80000 + ], + @[@"get", @"abbr"], + @[@"get", @"name"] + ], + @5, @[@"get", @"name"] + ]; + NSExpression *expression = [NSExpression expressionWithMGLJSONObject:jsonExpression]; + NSExpression *localizedExpression = [expression mgl_expressionLocalizedIntoLocale:[NSLocale localeWithLocaleIdentifier:@"mul"]]; + XCTAssertEqualObjects(localizedExpression.mgl_jsonExpressionObject, localizedJSONExpression); } } +- (void)testConvenienceInitializers { + { + NSExpression *expression = [NSExpression mgl_expressionForConditional:[NSPredicate predicateWithFormat:@"1 = 2"] + trueExpression:MGLConstantExpression(@YES) + falseExpresssion:MGLConstantExpression(@NO)]; + + NSArray *jsonExpression = @[@"case", @[@"==", @1, @2], @YES, @NO]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @NO); + } + { + NSDictionary *stops = @{@0: MGLConstantExpression(@111), @1: MGLConstantExpression(@1111)}; + NSExpression *expression = [NSExpression mgl_expressionForSteppingExpression:[NSExpression expressionForKeyPath:@"x"] + fromExpression:[NSExpression expressionForConstantValue:@11] + stops:[NSExpression expressionForConstantValue:stops]]; + NSArray *jsonExpression = @[@"step", @[@"get", @"x"], @11, @0, @111, @1, @1111]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSDictionary *stops = @{@0: MGLConstantExpression(@100), @10: MGLConstantExpression(@200)}; + NSExpression *expression = [NSExpression mgl_expressionForInterpolatingExpression:[NSExpression expressionForKeyPath:@"x"] + withCurveType:MGLExpressionInterpolationModeLinear + parameters:nil + stops:[NSExpression expressionForConstantValue:stops]]; + NSArray *jsonExpression = @[@"interpolate", @[@"linear"], @[@"get", @"x"], @0, @100, @10, @200]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSExpression *expression = [[NSExpression expressionForConstantValue:@"Old"] mgl_expressionByAppendingExpression:[NSExpression expressionForConstantValue:@"MacDonald"]]; + + NSArray *jsonExpression = @[@"concat", @"Old", @"MacDonald"]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @"OldMacDonald"); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } + { + NSDictionary *values = @{ MGLConstantExpression(@1): MGLConstantExpression(@"one") }; + NSExpression *expression = [NSExpression mgl_expressionForMatchingExpression:[NSExpression expressionWithFormat:@"2 * 1"] + inDictionary:values + defaultExpression:[NSExpression expressionForConstantValue:@"default"]]; + NSArray *jsonExpression = @[@"match", @[@"*", @2, @1], @1, @"one", @"default"]; + XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); + } +} + + @end diff --git a/platform/darwin/test/MGLFillExtrusionStyleLayerTests.mm b/platform/darwin/test/MGLFillExtrusionStyleLayerTests.mm index f5e26381d6..6081d104e1 100644 --- a/platform/darwin/test/MGLFillExtrusionStyleLayerTests.mm +++ b/platform/darwin/test/MGLFillExtrusionStyleLayerTests.mm @@ -30,8 +30,8 @@ XCTAssertNil(layer.sourceLayerIdentifier); XCTAssertNil(layer.predicate); - layer.predicate = [NSPredicate predicateWithValue:NO]; - XCTAssertEqualObjects(layer.predicate, [NSPredicate predicateWithValue:NO]); + layer.predicate = [NSPredicate predicateWithFormat:@"$featureIdentifier = 1"]; + XCTAssertEqualObjects(layer.predicate, [NSPredicate predicateWithFormat:@"$featureIdentifier = 1"]); layer.predicate = nil; XCTAssertNil(layer.predicate); } @@ -63,7 +63,7 @@ @"fillExtrusionBase should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.fillExtrusionBase = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -77,7 +77,7 @@ XCTAssertEqualObjects(layer.fillExtrusionBase, functionExpression, @"fillExtrusionBase should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.fillExtrusionBase = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -85,10 +85,11 @@ XCTAssertEqual(rawLayer->getFillExtrusionBase(), propertyValue, @"Setting fillExtrusionBase to a data expression should update fill-extrusion-base."); - XCTAssertEqualObjects(layer.fillExtrusionBase, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.fillExtrusionBase, pedanticFunctionExpression, @"fillExtrusionBase should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.fillExtrusionBase = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -98,7 +99,8 @@ XCTAssertEqual(rawLayer->getFillExtrusionBase(), propertyValue, @"Setting fillExtrusionBase to a camera-data expression should update fill-extrusion-base."); - XCTAssertEqualObjects(layer.fillExtrusionBase, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.fillExtrusionBase, pedanticFunctionExpression, @"fillExtrusionBase should round-trip camera-data expressions."); @@ -133,7 +135,7 @@ @"fillExtrusionColor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"%@", [MGLColor redColor]]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.fillExtrusionColor = functionExpression; mbgl::style::IntervalStops<mbgl::Color> intervalStops = {{ @@ -147,7 +149,7 @@ XCTAssertEqualObjects(layer.fillExtrusionColor, functionExpression, @"fillExtrusionColor should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.fillExtrusionColor = functionExpression; mbgl::style::ExponentialStops<mbgl::Color> exponentialStops = { {{18, { 1, 0, 0, 1 }}}, 1.0 }; @@ -155,10 +157,11 @@ XCTAssertEqual(rawLayer->getFillExtrusionColor(), propertyValue, @"Setting fillExtrusionColor to a data expression should update fill-extrusion-color."); - XCTAssertEqualObjects(layer.fillExtrusionColor, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.fillExtrusionColor, pedanticFunctionExpression, @"fillExtrusionColor should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.fillExtrusionColor = functionExpression; std::map<float, mbgl::Color> innerStops { {18, { 1, 0, 0, 1 }} }; @@ -168,7 +171,8 @@ XCTAssertEqual(rawLayer->getFillExtrusionColor(), propertyValue, @"Setting fillExtrusionColor to a camera-data expression should update fill-extrusion-color."); - XCTAssertEqualObjects(layer.fillExtrusionColor, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.fillExtrusionColor, pedanticFunctionExpression, @"fillExtrusionColor should round-trip camera-data expressions."); @@ -203,7 +207,7 @@ @"fillExtrusionHeight should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.fillExtrusionHeight = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -217,7 +221,7 @@ XCTAssertEqualObjects(layer.fillExtrusionHeight, functionExpression, @"fillExtrusionHeight should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.fillExtrusionHeight = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -225,10 +229,11 @@ XCTAssertEqual(rawLayer->getFillExtrusionHeight(), propertyValue, @"Setting fillExtrusionHeight to a data expression should update fill-extrusion-height."); - XCTAssertEqualObjects(layer.fillExtrusionHeight, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.fillExtrusionHeight, pedanticFunctionExpression, @"fillExtrusionHeight should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.fillExtrusionHeight = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -238,7 +243,8 @@ XCTAssertEqual(rawLayer->getFillExtrusionHeight(), propertyValue, @"Setting fillExtrusionHeight to a camera-data expression should update fill-extrusion-height."); - XCTAssertEqualObjects(layer.fillExtrusionHeight, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.fillExtrusionHeight, pedanticFunctionExpression, @"fillExtrusionHeight should round-trip camera-data expressions."); @@ -273,7 +279,7 @@ @"fillExtrusionOpacity should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.fillExtrusionOpacity = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -297,8 +303,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.fillExtrusionOpacity = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillExtrusionLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.fillExtrusionOpacity = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillExtrusionLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.fillExtrusionOpacityTransition = transitionTest; @@ -326,7 +332,7 @@ @"fillExtrusionPattern should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'Fill Extrusion Pattern'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.fillExtrusionPattern = functionExpression; mbgl::style::IntervalStops<std::string> intervalStops = {{ @@ -350,8 +356,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.fillExtrusionPattern = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillExtrusionLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.fillExtrusionPattern = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillExtrusionLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.fillExtrusionPatternTransition = transitionTest; @@ -385,7 +391,7 @@ @"fillExtrusionTranslation should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"{1, 1}"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.fillExtrusionTranslation = functionExpression; mbgl::style::IntervalStops<std::array<float, 2>> intervalStops = {{ @@ -409,8 +415,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.fillExtrusionTranslation = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillExtrusionLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.fillExtrusionTranslation = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillExtrusionLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -429,7 +435,7 @@ @"fillExtrusionTranslationAnchor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'viewport'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.fillExtrusionTranslationAnchor = functionExpression; mbgl::style::IntervalStops<mbgl::style::TranslateAnchorType> intervalStops = {{ @@ -453,8 +459,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.fillExtrusionTranslationAnchor = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillExtrusionLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.fillExtrusionTranslationAnchor = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillExtrusionLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } } diff --git a/platform/darwin/test/MGLFillStyleLayerTests.mm b/platform/darwin/test/MGLFillStyleLayerTests.mm index 25521f3ede..a5019f1032 100644 --- a/platform/darwin/test/MGLFillStyleLayerTests.mm +++ b/platform/darwin/test/MGLFillStyleLayerTests.mm @@ -30,8 +30,8 @@ XCTAssertNil(layer.sourceLayerIdentifier); XCTAssertNil(layer.predicate); - layer.predicate = [NSPredicate predicateWithValue:NO]; - XCTAssertEqualObjects(layer.predicate, [NSPredicate predicateWithValue:NO]); + layer.predicate = [NSPredicate predicateWithFormat:@"$featureIdentifier = 1"]; + XCTAssertEqualObjects(layer.predicate, [NSPredicate predicateWithFormat:@"$featureIdentifier = 1"]); layer.predicate = nil; XCTAssertNil(layer.predicate); } @@ -63,7 +63,7 @@ @"fillAntialiased should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"false"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.fillAntialiased = functionExpression; mbgl::style::IntervalStops<bool> intervalStops = {{ @@ -87,8 +87,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.fillAntialiased = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.fillAntialiased = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -107,7 +107,7 @@ @"fillColor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"%@", [MGLColor redColor]]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.fillColor = functionExpression; mbgl::style::IntervalStops<mbgl::Color> intervalStops = {{ @@ -121,7 +121,7 @@ XCTAssertEqualObjects(layer.fillColor, functionExpression, @"fillColor should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.fillColor = functionExpression; mbgl::style::ExponentialStops<mbgl::Color> exponentialStops = { {{18, { 1, 0, 0, 1 }}}, 1.0 }; @@ -129,10 +129,11 @@ XCTAssertEqual(rawLayer->getFillColor(), propertyValue, @"Setting fillColor to a data expression should update fill-color."); - XCTAssertEqualObjects(layer.fillColor, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.fillColor, pedanticFunctionExpression, @"fillColor should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.fillColor = functionExpression; std::map<float, mbgl::Color> innerStops { {18, { 1, 0, 0, 1 }} }; @@ -142,7 +143,8 @@ XCTAssertEqual(rawLayer->getFillColor(), propertyValue, @"Setting fillColor to a camera-data expression should update fill-color."); - XCTAssertEqualObjects(layer.fillColor, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.fillColor, pedanticFunctionExpression, @"fillColor should round-trip camera-data expressions."); @@ -177,7 +179,7 @@ @"fillOpacity should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.fillOpacity = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -191,7 +193,7 @@ XCTAssertEqualObjects(layer.fillOpacity, functionExpression, @"fillOpacity should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.fillOpacity = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -199,10 +201,11 @@ XCTAssertEqual(rawLayer->getFillOpacity(), propertyValue, @"Setting fillOpacity to a data expression should update fill-opacity."); - XCTAssertEqualObjects(layer.fillOpacity, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.fillOpacity, pedanticFunctionExpression, @"fillOpacity should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.fillOpacity = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -212,7 +215,8 @@ XCTAssertEqual(rawLayer->getFillOpacity(), propertyValue, @"Setting fillOpacity to a camera-data expression should update fill-opacity."); - XCTAssertEqualObjects(layer.fillOpacity, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.fillOpacity, pedanticFunctionExpression, @"fillOpacity should round-trip camera-data expressions."); @@ -247,7 +251,7 @@ @"fillOutlineColor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"%@", [MGLColor redColor]]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.fillOutlineColor = functionExpression; mbgl::style::IntervalStops<mbgl::Color> intervalStops = {{ @@ -261,7 +265,7 @@ XCTAssertEqualObjects(layer.fillOutlineColor, functionExpression, @"fillOutlineColor should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.fillOutlineColor = functionExpression; mbgl::style::ExponentialStops<mbgl::Color> exponentialStops = { {{18, { 1, 0, 0, 1 }}}, 1.0 }; @@ -269,10 +273,11 @@ XCTAssertEqual(rawLayer->getFillOutlineColor(), propertyValue, @"Setting fillOutlineColor to a data expression should update fill-outline-color."); - XCTAssertEqualObjects(layer.fillOutlineColor, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.fillOutlineColor, pedanticFunctionExpression, @"fillOutlineColor should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.fillOutlineColor = functionExpression; std::map<float, mbgl::Color> innerStops { {18, { 1, 0, 0, 1 }} }; @@ -282,7 +287,8 @@ XCTAssertEqual(rawLayer->getFillOutlineColor(), propertyValue, @"Setting fillOutlineColor to a camera-data expression should update fill-outline-color."); - XCTAssertEqualObjects(layer.fillOutlineColor, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.fillOutlineColor, pedanticFunctionExpression, @"fillOutlineColor should round-trip camera-data expressions."); @@ -317,7 +323,7 @@ @"fillPattern should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'Fill Pattern'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.fillPattern = functionExpression; mbgl::style::IntervalStops<std::string> intervalStops = {{ @@ -341,8 +347,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.fillPattern = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.fillPattern = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.fillPatternTransition = transitionTest; @@ -376,7 +382,7 @@ @"fillTranslation should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"{1, 1}"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.fillTranslation = functionExpression; mbgl::style::IntervalStops<std::array<float, 2>> intervalStops = {{ @@ -400,8 +406,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.fillTranslation = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.fillTranslation = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -420,7 +426,7 @@ @"fillTranslationAnchor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'viewport'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.fillTranslationAnchor = functionExpression; mbgl::style::IntervalStops<mbgl::style::TranslateAnchorType> intervalStops = {{ @@ -444,8 +450,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.fillTranslationAnchor = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.fillTranslationAnchor = functionExpression, NSException, NSInvalidArgumentException, @"MGLFillLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } } diff --git a/platform/darwin/test/MGLGeometryTests.mm b/platform/darwin/test/MGLGeometryTests.mm index 1c85470188..a0ddecf77e 100644 --- a/platform/darwin/test/MGLGeometryTests.mm +++ b/platform/darwin/test/MGLGeometryTests.mm @@ -163,4 +163,13 @@ [NSValue valueWithMGLCoordinate:quad.bottomRight], @"Quad bottom right should be computed correctly."); } + +- (void)testMGLMapPoint { + MGLMapPoint point = MGLMapPointForCoordinate(CLLocationCoordinate2DMake(37.936, -80.425), 0.0); + + MGLMapPoint roundTrippedPoint = [NSValue valueWithMGLMapPoint:point].MGLMapPointValue; + XCTAssertEqual(point.x, roundTrippedPoint.x); + XCTAssertEqual(point.y, roundTrippedPoint.y); + XCTAssertEqual(point.zoomLevel, roundTrippedPoint.zoomLevel); +} @end diff --git a/platform/darwin/test/MGLHeatmapColorTests.mm b/platform/darwin/test/MGLHeatmapColorTests.mm index 8d44064d94..bed777ae05 100644 --- a/platform/darwin/test/MGLHeatmapColorTests.mm +++ b/platform/darwin/test/MGLHeatmapColorTests.mm @@ -33,7 +33,7 @@ constantExpression = [NSExpression expressionWithFormat:@"%@", [MGLColor redColor]]; NSExpression *constantExpression2 = [NSExpression expressionWithFormat:@"%@", [MGLColor blueColor]]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($heatmapDensity, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@12: constantExpression2}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($heatmapDensity, %@, %@)", constantExpression, @{@12: constantExpression2}]; layer.heatmapColor = functionExpression; XCTAssertEqual(rawLayer->getHeatmapColor().evaluate(11.0), mbgl::Color::red(), @@ -46,15 +46,16 @@ layer.heatmapColor = nil; XCTAssertTrue(rawLayer->getHeatmapColor().isUndefined(), @"Unsetting heatmapColor should return heatmap-color to the default value."); - XCTAssertEqualObjects(layer.heatmapColor, defaultExpression, + // The contained colors aren’t object equal, even though their descriptions are. + XCTAssertEqualObjects(layer.heatmapColor.description, defaultExpression.description, @"heatmapColor should return the default value after being unset."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; XCTAssertThrowsSpecificNamed(layer.heatmapColor = functionExpression, NSException, NSInvalidArgumentException, @"MGLHeatmapLayer should raise an exception if a camera expression is applied to heatmapColor."); functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.heatmapColor = functionExpression, NSException, NSInvalidArgumentException, @"MGLHeatmapLayer should raise an exception if a data expression is applied to heatmapColor."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.heatmapColor = functionExpression, NSException, NSInvalidArgumentException, @"MGLHeatmapLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } diff --git a/platform/darwin/test/MGLHeatmapStyleLayerTests.mm b/platform/darwin/test/MGLHeatmapStyleLayerTests.mm index 74121affd8..e4b1917257 100644 --- a/platform/darwin/test/MGLHeatmapStyleLayerTests.mm +++ b/platform/darwin/test/MGLHeatmapStyleLayerTests.mm @@ -30,8 +30,8 @@ XCTAssertNil(layer.sourceLayerIdentifier); XCTAssertNil(layer.predicate); - layer.predicate = [NSPredicate predicateWithValue:NO]; - XCTAssertEqualObjects(layer.predicate, [NSPredicate predicateWithValue:NO]); + layer.predicate = [NSPredicate predicateWithFormat:@"$featureIdentifier = 1"]; + XCTAssertEqualObjects(layer.predicate, [NSPredicate predicateWithFormat:@"$featureIdentifier = 1"]); layer.predicate = nil; XCTAssertNil(layer.predicate); } @@ -63,7 +63,7 @@ @"heatmapIntensity should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.heatmapIntensity = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -87,8 +87,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.heatmapIntensity = functionExpression, NSException, NSInvalidArgumentException, @"MGLHeatmapLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.heatmapIntensity = functionExpression, NSException, NSInvalidArgumentException, @"MGLHeatmapLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.heatmapIntensityTransition = transitionTest; @@ -116,7 +116,7 @@ @"heatmapOpacity should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.heatmapOpacity = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -140,8 +140,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.heatmapOpacity = functionExpression, NSException, NSInvalidArgumentException, @"MGLHeatmapLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.heatmapOpacity = functionExpression, NSException, NSInvalidArgumentException, @"MGLHeatmapLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.heatmapOpacityTransition = transitionTest; @@ -169,7 +169,7 @@ @"heatmapRadius should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.heatmapRadius = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -183,7 +183,7 @@ XCTAssertEqualObjects(layer.heatmapRadius, functionExpression, @"heatmapRadius should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.heatmapRadius = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -191,10 +191,11 @@ XCTAssertEqual(rawLayer->getHeatmapRadius(), propertyValue, @"Setting heatmapRadius to a data expression should update heatmap-radius."); - XCTAssertEqualObjects(layer.heatmapRadius, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.heatmapRadius, pedanticFunctionExpression, @"heatmapRadius should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.heatmapRadius = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -204,7 +205,8 @@ XCTAssertEqual(rawLayer->getHeatmapRadius(), propertyValue, @"Setting heatmapRadius to a camera-data expression should update heatmap-radius."); - XCTAssertEqualObjects(layer.heatmapRadius, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.heatmapRadius, pedanticFunctionExpression, @"heatmapRadius should round-trip camera-data expressions."); @@ -239,7 +241,7 @@ @"heatmapWeight should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.heatmapWeight = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -253,7 +255,7 @@ XCTAssertEqualObjects(layer.heatmapWeight, functionExpression, @"heatmapWeight should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.heatmapWeight = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -261,10 +263,11 @@ XCTAssertEqual(rawLayer->getHeatmapWeight(), propertyValue, @"Setting heatmapWeight to a data expression should update heatmap-weight."); - XCTAssertEqualObjects(layer.heatmapWeight, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.heatmapWeight, pedanticFunctionExpression, @"heatmapWeight should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.heatmapWeight = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -274,7 +277,8 @@ XCTAssertEqual(rawLayer->getHeatmapWeight(), propertyValue, @"Setting heatmapWeight to a camera-data expression should update heatmap-weight."); - XCTAssertEqualObjects(layer.heatmapWeight, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.heatmapWeight, pedanticFunctionExpression, @"heatmapWeight should round-trip camera-data expressions."); diff --git a/platform/darwin/test/MGLHillshadeStyleLayerTests.mm b/platform/darwin/test/MGLHillshadeStyleLayerTests.mm index b0b7ddd5ee..34937d1674 100644 --- a/platform/darwin/test/MGLHillshadeStyleLayerTests.mm +++ b/platform/darwin/test/MGLHillshadeStyleLayerTests.mm @@ -45,7 +45,7 @@ @"hillshadeAccentColor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"%@", [MGLColor redColor]]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.hillshadeAccentColor = functionExpression; mbgl::style::IntervalStops<mbgl::Color> intervalStops = {{ @@ -69,8 +69,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.hillshadeAccentColor = functionExpression, NSException, NSInvalidArgumentException, @"MGLHillshadeLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.hillshadeAccentColor = functionExpression, NSException, NSInvalidArgumentException, @"MGLHillshadeLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.hillshadeAccentColorTransition = transitionTest; @@ -98,7 +98,7 @@ @"hillshadeExaggeration should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.hillshadeExaggeration = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -122,8 +122,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.hillshadeExaggeration = functionExpression, NSException, NSInvalidArgumentException, @"MGLHillshadeLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.hillshadeExaggeration = functionExpression, NSException, NSInvalidArgumentException, @"MGLHillshadeLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.hillshadeExaggerationTransition = transitionTest; @@ -151,7 +151,7 @@ @"hillshadeHighlightColor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"%@", [MGLColor redColor]]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.hillshadeHighlightColor = functionExpression; mbgl::style::IntervalStops<mbgl::Color> intervalStops = {{ @@ -175,8 +175,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.hillshadeHighlightColor = functionExpression, NSException, NSInvalidArgumentException, @"MGLHillshadeLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.hillshadeHighlightColor = functionExpression, NSException, NSInvalidArgumentException, @"MGLHillshadeLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.hillshadeHighlightColorTransition = transitionTest; @@ -204,7 +204,7 @@ @"hillshadeIlluminationAnchor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'viewport'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.hillshadeIlluminationAnchor = functionExpression; mbgl::style::IntervalStops<mbgl::style::HillshadeIlluminationAnchorType> intervalStops = {{ @@ -228,8 +228,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.hillshadeIlluminationAnchor = functionExpression, NSException, NSInvalidArgumentException, @"MGLHillshadeLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.hillshadeIlluminationAnchor = functionExpression, NSException, NSInvalidArgumentException, @"MGLHillshadeLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -248,7 +248,7 @@ @"hillshadeIlluminationDirection should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.hillshadeIlluminationDirection = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -272,8 +272,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.hillshadeIlluminationDirection = functionExpression, NSException, NSInvalidArgumentException, @"MGLHillshadeLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.hillshadeIlluminationDirection = functionExpression, NSException, NSInvalidArgumentException, @"MGLHillshadeLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -292,7 +292,7 @@ @"hillshadeShadowColor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"%@", [MGLColor redColor]]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.hillshadeShadowColor = functionExpression; mbgl::style::IntervalStops<mbgl::Color> intervalStops = {{ @@ -316,8 +316,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.hillshadeShadowColor = functionExpression, NSException, NSInvalidArgumentException, @"MGLHillshadeLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.hillshadeShadowColor = functionExpression, NSException, NSInvalidArgumentException, @"MGLHillshadeLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.hillshadeShadowColorTransition = transitionTest; diff --git a/platform/darwin/test/MGLLineStyleLayerTests.mm b/platform/darwin/test/MGLLineStyleLayerTests.mm index bf98e98320..5490278e98 100644 --- a/platform/darwin/test/MGLLineStyleLayerTests.mm +++ b/platform/darwin/test/MGLLineStyleLayerTests.mm @@ -30,8 +30,8 @@ XCTAssertNil(layer.sourceLayerIdentifier); XCTAssertNil(layer.predicate); - layer.predicate = [NSPredicate predicateWithValue:NO]; - XCTAssertEqualObjects(layer.predicate, [NSPredicate predicateWithValue:NO]); + layer.predicate = [NSPredicate predicateWithFormat:@"$featureIdentifier = 1"]; + XCTAssertEqualObjects(layer.predicate, [NSPredicate predicateWithFormat:@"$featureIdentifier = 1"]); layer.predicate = nil; XCTAssertNil(layer.predicate); } @@ -63,7 +63,7 @@ @"lineCap should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'square'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.lineCap = functionExpression; mbgl::style::IntervalStops<mbgl::style::LineCapType> intervalStops = {{ @@ -87,8 +87,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.lineCap = functionExpression, NSException, NSInvalidArgumentException, @"MGLLineLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.lineCap = functionExpression, NSException, NSInvalidArgumentException, @"MGLLineLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -107,7 +107,7 @@ @"lineJoin should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'miter'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.lineJoin = functionExpression; mbgl::style::IntervalStops<mbgl::style::LineJoinType> intervalStops = {{ @@ -145,7 +145,7 @@ @"lineMiterLimit should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.lineMiterLimit = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -169,8 +169,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.lineMiterLimit = functionExpression, NSException, NSInvalidArgumentException, @"MGLLineLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.lineMiterLimit = functionExpression, NSException, NSInvalidArgumentException, @"MGLLineLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -189,7 +189,7 @@ @"lineRoundLimit should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.lineRoundLimit = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -213,8 +213,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.lineRoundLimit = functionExpression, NSException, NSInvalidArgumentException, @"MGLLineLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.lineRoundLimit = functionExpression, NSException, NSInvalidArgumentException, @"MGLLineLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -233,7 +233,7 @@ @"lineBlur should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.lineBlur = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -247,7 +247,7 @@ XCTAssertEqualObjects(layer.lineBlur, functionExpression, @"lineBlur should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.lineBlur = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -255,10 +255,11 @@ XCTAssertEqual(rawLayer->getLineBlur(), propertyValue, @"Setting lineBlur to a data expression should update line-blur."); - XCTAssertEqualObjects(layer.lineBlur, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.lineBlur, pedanticFunctionExpression, @"lineBlur should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.lineBlur = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -268,7 +269,8 @@ XCTAssertEqual(rawLayer->getLineBlur(), propertyValue, @"Setting lineBlur to a camera-data expression should update line-blur."); - XCTAssertEqualObjects(layer.lineBlur, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.lineBlur, pedanticFunctionExpression, @"lineBlur should round-trip camera-data expressions."); @@ -303,7 +305,7 @@ @"lineColor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"%@", [MGLColor redColor]]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.lineColor = functionExpression; mbgl::style::IntervalStops<mbgl::Color> intervalStops = {{ @@ -317,7 +319,7 @@ XCTAssertEqualObjects(layer.lineColor, functionExpression, @"lineColor should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.lineColor = functionExpression; mbgl::style::ExponentialStops<mbgl::Color> exponentialStops = { {{18, { 1, 0, 0, 1 }}}, 1.0 }; @@ -325,10 +327,11 @@ XCTAssertEqual(rawLayer->getLineColor(), propertyValue, @"Setting lineColor to a data expression should update line-color."); - XCTAssertEqualObjects(layer.lineColor, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.lineColor, pedanticFunctionExpression, @"lineColor should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.lineColor = functionExpression; std::map<float, mbgl::Color> innerStops { {18, { 1, 0, 0, 1 }} }; @@ -338,7 +341,8 @@ XCTAssertEqual(rawLayer->getLineColor(), propertyValue, @"Setting lineColor to a camera-data expression should update line-color."); - XCTAssertEqualObjects(layer.lineColor, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.lineColor, pedanticFunctionExpression, @"lineColor should round-trip camera-data expressions."); @@ -373,7 +377,7 @@ @"lineDashPattern should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"{1, 2}"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.lineDashPattern = functionExpression; mbgl::style::IntervalStops<std::vector<float>> intervalStops = {{ @@ -397,8 +401,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.lineDashPattern = functionExpression, NSException, NSInvalidArgumentException, @"MGLLineLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.lineDashPattern = functionExpression, NSException, NSInvalidArgumentException, @"MGLLineLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -417,7 +421,7 @@ @"lineGapWidth should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.lineGapWidth = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -431,7 +435,7 @@ XCTAssertEqualObjects(layer.lineGapWidth, functionExpression, @"lineGapWidth should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.lineGapWidth = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -439,10 +443,11 @@ XCTAssertEqual(rawLayer->getLineGapWidth(), propertyValue, @"Setting lineGapWidth to a data expression should update line-gap-width."); - XCTAssertEqualObjects(layer.lineGapWidth, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.lineGapWidth, pedanticFunctionExpression, @"lineGapWidth should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.lineGapWidth = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -452,7 +457,8 @@ XCTAssertEqual(rawLayer->getLineGapWidth(), propertyValue, @"Setting lineGapWidth to a camera-data expression should update line-gap-width."); - XCTAssertEqualObjects(layer.lineGapWidth, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.lineGapWidth, pedanticFunctionExpression, @"lineGapWidth should round-trip camera-data expressions."); @@ -487,7 +493,7 @@ @"lineOffset should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.lineOffset = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -501,7 +507,7 @@ XCTAssertEqualObjects(layer.lineOffset, functionExpression, @"lineOffset should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.lineOffset = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -509,10 +515,11 @@ XCTAssertEqual(rawLayer->getLineOffset(), propertyValue, @"Setting lineOffset to a data expression should update line-offset."); - XCTAssertEqualObjects(layer.lineOffset, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.lineOffset, pedanticFunctionExpression, @"lineOffset should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.lineOffset = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -522,7 +529,8 @@ XCTAssertEqual(rawLayer->getLineOffset(), propertyValue, @"Setting lineOffset to a camera-data expression should update line-offset."); - XCTAssertEqualObjects(layer.lineOffset, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.lineOffset, pedanticFunctionExpression, @"lineOffset should round-trip camera-data expressions."); @@ -557,7 +565,7 @@ @"lineOpacity should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.lineOpacity = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -571,7 +579,7 @@ XCTAssertEqualObjects(layer.lineOpacity, functionExpression, @"lineOpacity should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.lineOpacity = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -579,10 +587,11 @@ XCTAssertEqual(rawLayer->getLineOpacity(), propertyValue, @"Setting lineOpacity to a data expression should update line-opacity."); - XCTAssertEqualObjects(layer.lineOpacity, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.lineOpacity, pedanticFunctionExpression, @"lineOpacity should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.lineOpacity = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -592,7 +601,8 @@ XCTAssertEqual(rawLayer->getLineOpacity(), propertyValue, @"Setting lineOpacity to a camera-data expression should update line-opacity."); - XCTAssertEqualObjects(layer.lineOpacity, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.lineOpacity, pedanticFunctionExpression, @"lineOpacity should round-trip camera-data expressions."); @@ -627,7 +637,7 @@ @"linePattern should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'Line Pattern'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.linePattern = functionExpression; mbgl::style::IntervalStops<std::string> intervalStops = {{ @@ -651,8 +661,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.linePattern = functionExpression, NSException, NSInvalidArgumentException, @"MGLLineLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.linePattern = functionExpression, NSException, NSInvalidArgumentException, @"MGLLineLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.linePatternTransition = transitionTest; @@ -686,7 +696,7 @@ @"lineTranslation should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"{1, 1}"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.lineTranslation = functionExpression; mbgl::style::IntervalStops<std::array<float, 2>> intervalStops = {{ @@ -710,8 +720,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.lineTranslation = functionExpression, NSException, NSInvalidArgumentException, @"MGLLineLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.lineTranslation = functionExpression, NSException, NSInvalidArgumentException, @"MGLLineLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -730,7 +740,7 @@ @"lineTranslationAnchor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'viewport'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.lineTranslationAnchor = functionExpression; mbgl::style::IntervalStops<mbgl::style::TranslateAnchorType> intervalStops = {{ @@ -754,8 +764,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.lineTranslationAnchor = functionExpression, NSException, NSInvalidArgumentException, @"MGLLineLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.lineTranslationAnchor = functionExpression, NSException, NSInvalidArgumentException, @"MGLLineLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -774,7 +784,7 @@ @"lineWidth should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.lineWidth = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -788,7 +798,7 @@ XCTAssertEqualObjects(layer.lineWidth, functionExpression, @"lineWidth should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.lineWidth = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -796,10 +806,11 @@ XCTAssertEqual(rawLayer->getLineWidth(), propertyValue, @"Setting lineWidth to a data expression should update line-width."); - XCTAssertEqualObjects(layer.lineWidth, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.lineWidth, pedanticFunctionExpression, @"lineWidth should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.lineWidth = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -809,7 +820,8 @@ XCTAssertEqual(rawLayer->getLineWidth(), propertyValue, @"Setting lineWidth to a camera-data expression should update line-width."); - XCTAssertEqualObjects(layer.lineWidth, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.lineWidth, pedanticFunctionExpression, @"lineWidth should round-trip camera-data expressions."); diff --git a/platform/darwin/test/MGLPredicateTests.mm b/platform/darwin/test/MGLPredicateTests.mm index d8cad0b166..ab4a7e2d88 100644 --- a/platform/darwin/test/MGLPredicateTests.mm +++ b/platform/darwin/test/MGLPredicateTests.mm @@ -23,295 +23,9 @@ namespace mbgl { @implementation MGLPredicateTests -- (void)testFilterization { - { - auto actual = [NSPredicate predicateWithValue:YES].mgl_filter; - mbgl::style::AllFilter expected; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithValue:NO].mgl_filter; - mbgl::style::AnyFilter expected; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"a = 'b'"].mgl_filter; - mbgl::style::EqualsFilter expected = { .key = "a", .value = std::string("b") }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"%K = 'Point'", @"$type"].mgl_filter; - mbgl::style::TypeEqualsFilter expected = { .value = mbgl::FeatureType::Point }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"%K = 67086180", @"$id"].mgl_filter; - mbgl::style::IdentifierEqualsFilter expected = { .value = UINT64_C(67086180) }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"%K = nil", @"$id"].mgl_filter; - mbgl::style::NotHasIdentifierFilter expected; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"a = nil"].mgl_filter; - mbgl::style::NotHasFilter expected = { .key = "a" }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"%K != 'Point'", @"$type"].mgl_filter; - mbgl::style::TypeNotEqualsFilter expected = { .value = mbgl::FeatureType::Point }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"%K != 67086180", @"$id"].mgl_filter; - mbgl::style::IdentifierNotEqualsFilter expected = { .value = UINT64_C(67086180) }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"%K != nil", @"$id"].mgl_filter; - mbgl::style::HasIdentifierFilter expected; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"a != 'b'"].mgl_filter; - mbgl::style::NotEqualsFilter expected = { .key = "a", .value = std::string("b") }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"a != nil"].mgl_filter; - mbgl::style::HasFilter expected = { .key = "a" }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"a < 'b'"].mgl_filter; - mbgl::style::LessThanFilter expected = { .key = "a", .value = std::string("b") }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"a <= 'b'"].mgl_filter; - mbgl::style::LessThanEqualsFilter expected = { .key = "a", .value = std::string("b") }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"a > 'b'"].mgl_filter; - mbgl::style::GreaterThanFilter expected = { .key = "a", .value = std::string("b") }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"a >= 'b'"].mgl_filter; - mbgl::style::GreaterThanEqualsFilter expected = { .key = "a", .value = std::string("b") }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"a BETWEEN {'b', 'z'}"].mgl_filter; - mbgl::style::AllFilter expected = { - .filters = { - mbgl::style::GreaterThanEqualsFilter { .key = "a", .value = std::string("b") }, - mbgl::style::LessThanEqualsFilter { .key = "a", .value = std::string("z") }, - }, - }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"a BETWEEN %@", @[@"b", @"z"]].mgl_filter; - mbgl::style::AllFilter expected = { - .filters = { - mbgl::style::GreaterThanEqualsFilter { .key = "a", .value = std::string("b") }, - mbgl::style::LessThanEqualsFilter { .key = "a", .value = std::string("z") }, - }, - }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"a IN {'b', 'c'}"].mgl_filter; - mbgl::style::InFilter expected = { .key = "a", .values = { std::string("b"), std::string("c") } }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"a IN %@", @[@"b", @"c"]].mgl_filter; - mbgl::style::InFilter expected = { .key = "a", .values = { std::string("b"), std::string("c") } }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"%K IN {'LineString', 'Polygon'}", @"$type"].mgl_filter; - mbgl::style::TypeInFilter expected = { .values = { mbgl::FeatureType::LineString, mbgl::FeatureType::Polygon } }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"%K IN %@", @"$type", @[@"LineString", @"Polygon"]].mgl_filter; - mbgl::style::TypeInFilter expected = { .values = { mbgl::FeatureType::LineString, mbgl::FeatureType::Polygon } }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"%K IN {67086180, 3709678893, 3352016856, 4189833989}", @"$id"].mgl_filter; - mbgl::style::IdentifierInFilter expected = { .values = { UINT64_C(67086180), UINT64_C(3709678893), UINT64_C(3352016856), UINT64_C(4189833989) } }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"%K IN %@", @"$id", @[@67086180, @3709678893, @3352016856, @4189833989]].mgl_filter; - mbgl::style::IdentifierInFilter expected = { .values = { UINT64_C(67086180), UINT64_C(3709678893), UINT64_C(3352016856), UINT64_C(4189833989) } }; - MGLAssertEqualFilters(actual, expected); - } - - XCTAssertThrowsSpecificNamed([NSPredicate predicateWithFormat:@"'Mapbox' IN a"].mgl_filter, NSException, NSInvalidArgumentException); - - { - auto actual = [NSPredicate predicateWithFormat:@"{'b', 'c'} CONTAINS a"].mgl_filter; - mbgl::style::InFilter expected = { .key = "a", .values = { std::string("b"), std::string("c") } }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"%@ CONTAINS a", @[@"b", @"c"]].mgl_filter; - mbgl::style::InFilter expected = { .key = "a", .values = { std::string("b"), std::string("c") } }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"%@ CONTAINS %K", @[@"LineString", @"Polygon"], @"$type"].mgl_filter; - mbgl::style::TypeInFilter expected = { .values = { mbgl::FeatureType::LineString, mbgl::FeatureType::Polygon } }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"{67086180, 3709678893, 3352016856, 4189833989} CONTAINS %K", @"$id"].mgl_filter; - mbgl::style::IdentifierInFilter expected = { .values = { UINT64_C(67086180), UINT64_C(3709678893), UINT64_C(3352016856), UINT64_C(4189833989) } }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"%@ CONTAINS %K", @[@67086180, @3709678893, @3352016856, @4189833989], @"$id"].mgl_filter; - mbgl::style::IdentifierInFilter expected = { .values = { UINT64_C(67086180), UINT64_C(3709678893), UINT64_C(3352016856), UINT64_C(4189833989) } }; - MGLAssertEqualFilters(actual, expected); - } - - XCTAssertThrowsSpecificNamed([NSPredicate predicateWithFormat:@"a CONTAINS 'Mapbox'"].mgl_filter, NSException, NSInvalidArgumentException); - - { - auto actual = [NSPredicate predicateWithFormat:@"a == 'b' AND c == 'd'"].mgl_filter; - mbgl::style::AllFilter expected = { - .filters = { - mbgl::style::EqualsFilter { .key = "a", .value = std::string("b") }, - mbgl::style::EqualsFilter { .key = "c", .value = std::string("d") }, - }, - }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"a == 'b' OR c == 'd'"].mgl_filter; - mbgl::style::AnyFilter expected = { - .filters = { - mbgl::style::EqualsFilter { .key = "a", .value = std::string("b") }, - mbgl::style::EqualsFilter { .key = "c", .value = std::string("d") }, - }, - }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"NOT(a == 'b' AND c == 'd')"].mgl_filter; - mbgl::style::NoneFilter expected = { - .filters = { - mbgl::style::AllFilter { - .filters = { - mbgl::style::EqualsFilter { .key = "a", .value = std::string("b") }, - mbgl::style::EqualsFilter { .key = "c", .value = std::string("d") }, - }, - }, - }, - }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"NOT(a == 'b' OR c == 'd')"].mgl_filter; - mbgl::style::NoneFilter expected = { - .filters = { - mbgl::style::EqualsFilter { .key = "a", .value = std::string("b") }, - mbgl::style::EqualsFilter { .key = "c", .value = std::string("d") }, - }, - }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"NOT a == nil"].mgl_filter; - mbgl::style::HasFilter expected = { .key = "a" }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"NOT a != nil"].mgl_filter; - mbgl::style::NotHasFilter expected = { .key = "a" }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"NOT a IN {'b', 'c'}"].mgl_filter; - mbgl::style::NotInFilter expected = { .key = "a", .values = { std::string("b"), std::string("c") } }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"NOT a IN %@", @[@"b", @"c"]].mgl_filter; - mbgl::style::NotInFilter expected = { .key = "a", .values = { std::string("b"), std::string("c") } }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"NOT {'b', 'c'} CONTAINS a"].mgl_filter; - mbgl::style::NotInFilter expected = { .key = "a", .values = { std::string("b"), std::string("c") } }; - MGLAssertEqualFilters(actual, expected); - } - - { - auto actual = [NSPredicate predicateWithFormat:@"NOT %@ CONTAINS a", @[@"b", @"c"]].mgl_filter; - mbgl::style::NotInFilter expected = { .key = "a", .values = { std::string("b"), std::string("c") } }; - MGLAssertEqualFilters(actual, expected); - } - - 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: %@)", [MGLPolyline 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)testPredication { XCTAssertNil([NSPredicate mgl_predicateWithFilter:mbgl::style::NullFilter()]); - + { mbgl::style::EqualsFilter filter = { .key = "a", .value = std::string("b") }; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter], [NSPredicate predicateWithFormat:@"a = 'b'"]); @@ -351,12 +65,12 @@ namespace mbgl { mbgl::style::TypeEqualsFilter filter = { .value = mbgl::FeatureType::Unknown }; XCTAssertThrowsSpecificNamed([NSPredicate mgl_predicateWithFilter:filter], NSException, NSInternalInconsistencyException); } - + { mbgl::style::NotHasFilter filter = { .key = "a" }; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter], [NSPredicate predicateWithFormat:@"a = nil"]); } - + { mbgl::style::NotEqualsFilter filter = { .key = "a", .value = std::string("b") }; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter], [NSPredicate predicateWithFormat:@"a != 'b'"]); @@ -379,32 +93,32 @@ namespace mbgl { NSPredicate *expected = [NSPredicate predicateWithFormat:@"%K != nil", @"$id"]; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter], expected); } - + { mbgl::style::HasFilter filter = { .key = "a" }; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter], [NSPredicate predicateWithFormat:@"a != nil"]); } - + { mbgl::style::LessThanFilter filter = { .key = "a", .value = std::string("b") }; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter], [NSPredicate predicateWithFormat:@"a < 'b'"]); } - + { mbgl::style::LessThanEqualsFilter filter = { .key = "a", .value = std::string("b") }; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter], [NSPredicate predicateWithFormat:@"a <= 'b'"]); } - + { mbgl::style::GreaterThanFilter filter = { .key = "a", .value = std::string("b") }; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter], [NSPredicate predicateWithFormat:@"a > 'b'"]); } - + { mbgl::style::GreaterThanEqualsFilter filter = { .key = "a", .value = std::string("b") }; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter], [NSPredicate predicateWithFormat:@"a >= 'b'"]); } - + { mbgl::style::AllFilter filter = { .filters = { @@ -414,7 +128,7 @@ namespace mbgl { }; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter], [NSPredicate predicateWithFormat:@"a BETWEEN {'b', 'z'}"]); } - + { mbgl::style::AllFilter filter = { .filters = { @@ -424,7 +138,7 @@ namespace mbgl { }; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter], [NSPredicate predicateWithFormat:@"a BETWEEN {'b', 'z'}"]); } - + { mbgl::style::InFilter filter = { .key = "a", .values = { std::string("b"), std::string("c") } }; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter].predicateFormat, [NSPredicate predicateWithFormat:@"a IN {'b', 'c'}"].predicateFormat); @@ -441,7 +155,7 @@ namespace mbgl { NSPredicate *expected = [NSPredicate predicateWithFormat:@"%K IN {67086180, 3709678893, 3352016856, 4189833989}", @"$id"]; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter], expected); } - + { mbgl::style::NotInFilter filter = { .key = "a", .values = { std::string("b"), std::string("c") } }; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter].predicateFormat, [NSPredicate predicateWithFormat:@"NOT a IN {'b', 'c'}"].predicateFormat); @@ -458,12 +172,12 @@ namespace mbgl { NSPredicate *expected = [NSPredicate predicateWithFormat:@"NOT %K IN {67086180, 3709678893, 3352016856, 4189833989}", @"$id"]; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter], expected); } - + { mbgl::style::AllFilter filter; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter], [NSPredicate predicateWithValue:YES]); } - + { mbgl::style::AllFilter filter = { .filters = { @@ -473,12 +187,12 @@ namespace mbgl { }; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter], [NSPredicate predicateWithFormat:@"a == 'b' AND c == 'd'"]); } - + { mbgl::style::AnyFilter filter; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter], [NSPredicate predicateWithValue:NO]); } - + { mbgl::style::AnyFilter filter = { .filters = { @@ -488,12 +202,12 @@ namespace mbgl { }; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter], [NSPredicate predicateWithFormat:@"a == 'b' OR c == 'd'"]); } - + { mbgl::style::NoneFilter filter; XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:filter], [NSPredicate predicateWithValue:YES]); } - + { mbgl::style::NoneFilter filter = { .filters = { @@ -505,76 +219,339 @@ namespace mbgl { } } -- (void)testSymmetry { - [self testSymmetryWithFormat:@"a = 1" reverseFormat:@"1 = a" mustRoundTrip:YES]; - [self testSymmetryWithFormat:@"a != 1" reverseFormat:@"1 != a" mustRoundTrip:YES]; - XCTAssertThrowsSpecificNamed([NSPredicate predicateWithFormat:@"a = b"].mgl_filter, NSException, NSInvalidArgumentException); - XCTAssertThrowsSpecificNamed([NSPredicate predicateWithFormat:@"1 = 1"].mgl_filter, NSException, NSInvalidArgumentException); - - // In the predicate format language, $ is a special character denoting a - // variable. Use %K to escape the special feature attribute $id. - XCTAssertThrowsSpecificNamed([NSPredicate predicateWithFormat:@"$id == 670861802"].mgl_filter, NSException, NSInvalidArgumentException); - XCTAssertThrowsSpecificNamed([NSPredicate predicateWithFormat:@"a = $id"].mgl_filter, NSException, NSInvalidArgumentException); - - [self testSymmetryWithFormat:@"a = nil" reverseFormat:@"nil = a" mustRoundTrip:YES]; - [self testSymmetryWithFormat:@"a != nil" reverseFormat:@"nil != a" mustRoundTrip:YES]; - - [self testSymmetryWithFormat:@"a < 1" reverseFormat:@"1 > a" mustRoundTrip:YES]; - [self testSymmetryWithFormat:@"a <= 1" reverseFormat:@"1 >= a" mustRoundTrip:YES]; - [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:@"1 <= a && 2 >= a" mustRoundTrip:YES]; - [self testSymmetryWithPredicate:[NSPredicate predicateWithFormat:@"a BETWEEN %@", @[@1, @2]] - 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]]; - XCTAssertThrowsSpecificNamed(betweenSetPredicate.mgl_filter, NSException, NSInvalidArgumentException); - XCTAssertThrowsSpecificNamed([NSPredicate predicateWithFormat:@"a BETWEEN {1}"].mgl_filter, NSException, NSInvalidArgumentException); - XCTAssertThrowsSpecificNamed([NSPredicate predicateWithFormat:@"a BETWEEN {1, 2, 3}"].mgl_filter, NSException, NSInvalidArgumentException); - - [self testSymmetryWithFormat:@"a IN {1, 2}" reverseFormat:@"{1, 2} CONTAINS a" mustRoundTrip:NO]; - [self testSymmetryWithPredicate:[NSPredicate predicateWithFormat:@"a IN %@", @[@1, @2]] - reversePredicate:[NSPredicate predicateWithFormat:@"%@ CONTAINS a", @[@1, @2]] - mustRoundTrip:YES]; +- (void)testUnsupportedFilterPredicates { + XCTAssertThrowsSpecificNamed([NSPredicate predicateWithFormat:@"1 == 2"].mgl_filter, NSException, NSInvalidArgumentException); + XCTAssertThrowsSpecificNamed([NSPredicate predicateWithFormat:@"1 == 1"].mgl_filter, NSException, NSInvalidArgumentException); + XCTAssertThrowsSpecificNamed([NSPredicate predicateWithValue:YES].mgl_filter, NSException, NSInvalidArgumentException); + XCTAssertThrowsSpecificNamed([NSPredicate predicateWithValue:NO].mgl_filter, NSException, NSInvalidArgumentException); + 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: %@)", [MGLPolyline 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); +} - // 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:@"%@ CONTAINS a", @[@1, @2]] - mustRoundTrip:NO]; +- (void)testComparisonPredicates { + { + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"x == YES"]; + NSArray *jsonExpression = @[@"==", @[@"get", @"x"], @YES]; + XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression); + XCTAssertEqualObjects([NSPredicate mgl_predicateWithJSONObject:jsonExpression], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject: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 mgl_predicateWithJSONObject:jsonExpression], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject: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 mgl_predicateWithJSONObject:jsonExpression], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject: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 mgl_predicateWithJSONObject:jsonExpression], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject: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 mgl_predicateWithJSONObject:jsonExpression], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject: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 mgl_predicateWithJSONObject:jsonExpression], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject: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 mgl_predicateWithJSONObject:jsonExpression], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject: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 mgl_predicateWithJSONObject:jsonExpression], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject: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 mgl_predicateWithJSONObject:jsonExpression], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject: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 mgl_predicateWithJSONObject:jsonExpression], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject: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 mgl_predicateWithJSONObject:jsonExpression], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject: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 mgl_predicateWithJSONObject:jsonExpression], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject: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 mgl_predicateWithJSONObject:expected], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject: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 mgl_predicateWithJSONObject:expected], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject: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 mgl_predicateWithJSONObject:expected], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject:expected] + mustRoundTrip:NO]; + } + { + NSArray *expected = @[@"match", @[@"id"], @6, @YES, @5, @YES, @4, @YES, @3, @YES, @NO]; + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"$featureIdentifier IN { 6, 5, 4, 3}"]; + XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected); + NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"MGL_MATCH(CAST($featureIdentifier, 'NSNumber'), 3, YES, 4, YES, 5, YES, 6, YES, NO) == YES"]; + auto forwardFilter = [NSPredicate mgl_predicateWithJSONObject:expected].mgl_filter; + NSPredicate *forwardPredicateAfter = [NSPredicate mgl_predicateWithFilter:forwardFilter]; + XCTAssertEqualObjects(predicateAfter, forwardPredicateAfter); + } + { + 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); + NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"NOT MGL_MATCH(CAST(x, 'NSNumber'), 3, YES, 4, YES, 5, YES, 6, YES, NO) == YES"]; + auto forwardFilter = [NSPredicate mgl_predicateWithJSONObject:expected].mgl_filter; + NSPredicate *forwardPredicateAfter = [NSPredicate mgl_predicateWithFilter:forwardFilter]; + XCTAssertEqualObjects(predicateAfter, forwardPredicateAfter); + } + { + NSArray *expected = @[@"match", @[@"get", @"a"], @"b", @YES, @"c", @YES, @NO]; + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"a IN { 'b', 'c' }"]; + XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected); + NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"MGL_MATCH(CAST(a, 'NSString'), 'b', YES, 'c', YES, NO) == YES"]; + auto forwardFilter = [NSPredicate mgl_predicateWithJSONObject:expected].mgl_filter; + NSPredicate *forwardPredicateAfter = [NSPredicate mgl_predicateWithFilter:forwardFilter]; + XCTAssertEqualObjects(predicateAfter, forwardPredicateAfter); + } + { + NSArray *expected = @[@"match", @[@"geometry-type"], @"LineString", @YES, @"Polygon", @YES, @NO]; + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%@ IN %@", [NSExpression expressionForVariable:@"geometryType"], @[@"LineString", @"Polygon"]]; + XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected); + NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"MGL_MATCH($geometryType, 'LineString', YES, 'Polygon', YES, NO) == YES"]; + auto forwardFilter = [NSPredicate mgl_predicateWithJSONObject:expected].mgl_filter; + NSPredicate *forwardPredicateAfter = [NSPredicate mgl_predicateWithFilter:forwardFilter]; + XCTAssertEqualObjects(predicateAfter, forwardPredicateAfter); + } + { + 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); + NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"MGL_MATCH(CAST(x, 'NSNumber'), 3, YES, 4, YES, 5, YES, 6, YES, NO) == YES"]; + auto forwardFilter = [NSPredicate mgl_predicateWithJSONObject:expected].mgl_filter; + NSPredicate *forwardPredicateAfter = [NSPredicate mgl_predicateWithFilter:forwardFilter]; + XCTAssertEqualObjects(predicateAfter, forwardPredicateAfter); + } + { + NSArray *expected = @[@"match", @[@"geometry-type"], @"LineString", @YES, @"Polygon", @YES, @NO]; + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%@ CONTAINS %@", @[@"LineString", @"Polygon"], [NSExpression expressionForVariable:@"geometryType"]]; + XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected); + NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"MGL_MATCH($geometryType, 'LineString', YES, 'Polygon', YES, NO) == YES"]; + auto forwardFilter = [NSPredicate mgl_predicateWithJSONObject:expected].mgl_filter; + NSPredicate *forwardPredicateAfter = [NSPredicate mgl_predicateWithFilter:forwardFilter]; + XCTAssertEqualObjects(predicateAfter, forwardPredicateAfter); + } + { + NSArray *expected = @[@"match", @[@"id"], @6, @YES, @5, @YES, @4, @YES, @3, @YES, @NO]; + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"{ 6, 5, 4, 3} CONTAINS $featureIdentifier"]; + XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected); + NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"MGL_MATCH(CAST($featureIdentifier, 'NSNumber'), 3, YES, 4, YES, 5, YES, 6, YES, NO) == YES"]; + auto forwardFilter = [NSPredicate mgl_predicateWithJSONObject:expected].mgl_filter; + NSPredicate *forwardPredicateAfter = [NSPredicate mgl_predicateWithFilter:forwardFilter]; + XCTAssertEqualObjects(predicateAfter, forwardPredicateAfter); + } } -- (void)testSymmetryWithFormat:(NSString *)forwardFormat reverseFormat:(NSString *)reverseFormat mustRoundTrip:(BOOL)mustRoundTrip { - NSPredicate *forwardPredicate = [NSPredicate predicateWithFormat:forwardFormat]; - NSPredicate *reversePredicate = reverseFormat ? [NSPredicate predicateWithFormat:reverseFormat] : nil; - [self testSymmetryWithPredicate:forwardPredicate reversePredicate:reversePredicate mustRoundTrip:mustRoundTrip]; +- (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 mgl_predicateWithJSONObject:jsonExpression], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject: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 mgl_predicateWithJSONObject:jsonExpression], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject: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 mgl_predicateWithJSONObject:jsonExpression], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject: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 mgl_predicateWithJSONObject:jsonExpression], predicate); + [self testSymmetryWithPredicate:[NSPredicate mgl_predicateWithJSONObject: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 reversePredicate:(NSPredicate *)reversePredicate mustRoundTrip:(BOOL)mustRoundTrip { +- (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, forwardPredicateAfter.predicateFormat); - } - - if (reversePredicate) { - auto reverseFilter = reversePredicate.mgl_filter; - NSPredicate *reversePredicateAfter = [NSPredicate mgl_predicateWithFilter:reverseFilter]; - XCTAssertNotEqualObjects(reversePredicate, reversePredicateAfter); - - XCTAssertEqualObjects(forwardPredicateAfter, reversePredicateAfter); - } -} - -- (void)testComparisonExpressionArray { - { - NSArray *expected = @[@"==", @1, @2]; - XCTAssertEqualObjects([NSPredicate predicateWithFormat:@"1 = 2"].mgl_jsonExpressionObject, expected); + } else { + XCTAssertEqualObjects(forwardPredicate, forwardPredicateAfter); } } diff --git a/platform/darwin/test/MGLRasterStyleLayerTests.mm b/platform/darwin/test/MGLRasterStyleLayerTests.mm index 5ded23ee3c..c8e454743e 100644 --- a/platform/darwin/test/MGLRasterStyleLayerTests.mm +++ b/platform/darwin/test/MGLRasterStyleLayerTests.mm @@ -45,7 +45,7 @@ @"maximumRasterBrightness should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.maximumRasterBrightness = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -69,8 +69,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.maximumRasterBrightness = functionExpression, NSException, NSInvalidArgumentException, @"MGLRasterLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.maximumRasterBrightness = functionExpression, NSException, NSInvalidArgumentException, @"MGLRasterLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -89,7 +89,7 @@ @"minimumRasterBrightness should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.minimumRasterBrightness = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -113,8 +113,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.minimumRasterBrightness = functionExpression, NSException, NSInvalidArgumentException, @"MGLRasterLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.minimumRasterBrightness = functionExpression, NSException, NSInvalidArgumentException, @"MGLRasterLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -133,7 +133,7 @@ @"rasterContrast should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.rasterContrast = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -157,8 +157,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.rasterContrast = functionExpression, NSException, NSInvalidArgumentException, @"MGLRasterLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.rasterContrast = functionExpression, NSException, NSInvalidArgumentException, @"MGLRasterLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.rasterContrastTransition = transitionTest; @@ -186,7 +186,7 @@ @"rasterFadeDuration should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.rasterFadeDuration = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -210,8 +210,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.rasterFadeDuration = functionExpression, NSException, NSInvalidArgumentException, @"MGLRasterLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.rasterFadeDuration = functionExpression, NSException, NSInvalidArgumentException, @"MGLRasterLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -230,7 +230,7 @@ @"rasterHueRotation should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.rasterHueRotation = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -254,8 +254,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.rasterHueRotation = functionExpression, NSException, NSInvalidArgumentException, @"MGLRasterLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.rasterHueRotation = functionExpression, NSException, NSInvalidArgumentException, @"MGLRasterLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -274,7 +274,7 @@ @"rasterOpacity should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.rasterOpacity = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -298,8 +298,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.rasterOpacity = functionExpression, NSException, NSInvalidArgumentException, @"MGLRasterLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.rasterOpacity = functionExpression, NSException, NSInvalidArgumentException, @"MGLRasterLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.rasterOpacityTransition = transitionTest; @@ -327,7 +327,7 @@ @"rasterSaturation should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.rasterSaturation = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -351,8 +351,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.rasterSaturation = functionExpression, NSException, NSInvalidArgumentException, @"MGLRasterLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.rasterSaturation = functionExpression, NSException, NSInvalidArgumentException, @"MGLRasterLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); // Transition property test layer.rasterSaturationTransition = transitionTest; diff --git a/platform/darwin/test/MGLSDKTestHelpers.swift b/platform/darwin/test/MGLSDKTestHelpers.swift index 576e3da86b..727d8bf0c6 100644 --- a/platform/darwin/test/MGLSDKTestHelpers.swift +++ b/platform/darwin/test/MGLSDKTestHelpers.swift @@ -23,9 +23,9 @@ extension MGLSDKTestHelpers { class func protocolMethodDescriptions(_ p: Protocol) -> Set<String> { var methods = Set<String>() var methodCount = UInt32() - let methodDescriptionList: UnsafeMutablePointer<objc_method_description>! = protocol_copyMethodDescriptionList(p, false, true, &methodCount) + let methodDescriptionList = protocol_copyMethodDescriptionList(p, false, true, &methodCount) for i in 0..<Int(methodCount) { - let description: objc_method_description = methodDescriptionList[i] + let description = methodDescriptionList![i] XCTAssertNotNil(description.name?.description) methods.insert(description.name!.description) } @@ -36,11 +36,16 @@ extension MGLSDKTestHelpers { class func classMethodDescriptions(_ cls: Swift.AnyClass) -> Set<String> { var methods = Set<String>() var methodCount = UInt32() - let methodList: UnsafeMutablePointer<Method?>! = class_copyMethodList(cls, &methodCount) + let methodList = class_copyMethodList(cls, &methodCount) for i in 0..<Int(methodCount) { - let method = methodList[i] - let selector : Selector = method_getName(method) - methods.insert(selector.description) + let method = methodList![i] + let selector = method_getName(method) + #if os(macOS) + methods.insert(selector.description) + #else + XCTAssertNotNil(selector) + methods.insert(selector!.description) + #endif } free(methodList) return methods diff --git a/platform/darwin/test/MGLShapeSourceTests.mm b/platform/darwin/test/MGLShapeSourceTests.mm index 868dca730a..d3f9a599e2 100644 --- a/platform/darwin/test/MGLShapeSourceTests.mm +++ b/platform/darwin/test/MGLShapeSourceTests.mm @@ -2,7 +2,6 @@ #import <Mapbox/Mapbox.h> #import "MGLFeature_Private.h" -#import "MGLAbstractShapeSource_Private.h" #import "MGLShapeSource_Private.h" #import "MGLSource_Private.h" diff --git a/platform/darwin/test/MGLSourceQueryTests.m b/platform/darwin/test/MGLSourceQueryTests.m index d1ef180a52..b321da1ea4 100644 --- a/platform/darwin/test/MGLSourceQueryTests.m +++ b/platform/darwin/test/MGLSourceQueryTests.m @@ -7,8 +7,8 @@ @implementation MGLSourceQueryTests -- (void) testQueryVectorSource { - MGLVectorSource *source = [[MGLVectorSource alloc] initWithIdentifier:@"vector" tileURLTemplates:@[@"fake"] options:nil]; +- (void) testQueryVectorTileSource { + MGLVectorTileSource *source = [[MGLVectorTileSource alloc] initWithIdentifier:@"vector" tileURLTemplates:@[@"fake"] options:nil]; NSSet *sourceLayers = [NSSet setWithObjects:@"buildings", @"water", nil]; NSArray* features = [source featuresInSourceLayersWithIdentifiers:sourceLayers predicate:nil]; // Source not added yet, so features is 0 diff --git a/platform/darwin/test/MGLStyleLayerTests.mm.ejs b/platform/darwin/test/MGLStyleLayerTests.mm.ejs index e17501ed18..f70f0bba23 100644 --- a/platform/darwin/test/MGLStyleLayerTests.mm.ejs +++ b/platform/darwin/test/MGLStyleLayerTests.mm.ejs @@ -36,8 +36,8 @@ XCTAssertNil(layer.sourceLayerIdentifier); XCTAssertNil(layer.predicate); - layer.predicate = [NSPredicate predicateWithValue:NO]; - XCTAssertEqualObjects(layer.predicate, [NSPredicate predicateWithValue:NO]); + layer.predicate = [NSPredicate predicateWithFormat:@"$featureIdentifier = 1"]; + XCTAssertEqualObjects(layer.predicate, [NSPredicate predicateWithFormat:@"$featureIdentifier = 1"]); layer.predicate = nil; XCTAssertNil(layer.predicate); } @@ -80,7 +80,7 @@ @"<%- objCName(property) %> should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:<%- objCTestValue(property, type, false, 3) %>]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.<%- objCName(property) %> = functionExpression; mbgl::style::IntervalStops<<%- mbglType(property) %>> intervalStops = {{ @@ -95,7 +95,7 @@ @"<%- objCName(property) %> should round-trip camera expressions."); <% if (property["property-function"] && isInterpolatable(property)) { -%> - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.<%- objCName(property) %> = functionExpression; mbgl::style::ExponentialStops<<%- mbglType(property) %>> exponentialStops = { {{18, <%- mbglTestValue(property, type) %>}}, 1.0 }; @@ -103,10 +103,11 @@ XCTAssertEqual(rawLayer->get<%- camelize(originalPropertyName(property)) %>(), propertyValue, @"Setting <%- objCName(property) %> to a data expression should update <%- originalPropertyName(property) %>."); - XCTAssertEqualObjects(layer.<%- objCName(property) %>, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.<%- objCName(property) %>, pedanticFunctionExpression, @"<%- objCName(property) %> should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.<%- objCName(property) %> = functionExpression; std::map<float, <%- mbglType(property) %>> innerStops { {18, <%- mbglTestValue(property, type) %>} }; @@ -116,7 +117,8 @@ XCTAssertEqual(rawLayer->get<%- camelize(originalPropertyName(property)) %>(), propertyValue, @"Setting <%- objCName(property) %> to a camera-data expression should update <%- originalPropertyName(property) %>."); - XCTAssertEqualObjects(layer.<%- objCName(property) %>, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.<%- objCName(property) %>, pedanticFunctionExpression, @"<%- objCName(property) %> should round-trip camera-data expressions."); <% } -%> <% if (!property.required) { -%> @@ -131,8 +133,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.<%- objCName(property) %> = functionExpression, NSException, NSInvalidArgumentException, @"MGL<%- camelize(type) %>Layer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.<%- objCName(property) %> = functionExpression, NSException, NSInvalidArgumentException, @"MGL<%- camelize(type) %>Layer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); <% } -%> <% if (property["transition"] && !property.original) { -%> diff --git a/platform/darwin/test/MGLStyleTests.mm b/platform/darwin/test/MGLStyleTests.mm index 8f610e338c..6048f39ea3 100644 --- a/platform/darwin/test/MGLStyleTests.mm +++ b/platform/darwin/test/MGLStyleTests.mm @@ -1,6 +1,7 @@ #import <Mapbox/Mapbox.h> #import "NSBundle+MGLAdditions.h" +#import "MGLVectorTileSource_Private.h" #import <mbgl/util/default_styles.hpp> @@ -64,12 +65,6 @@ XCTAssertEqualObjects([MGLStyle darkStyleURL].absoluteString, @(mbgl::util::default_styles::dark.url)); XCTAssertEqualObjects([MGLStyle satelliteStyleURL].absoluteString, @(mbgl::util::default_styles::satellite.url)); XCTAssertEqualObjects([MGLStyle satelliteStreetsStyleURL].absoluteString, @(mbgl::util::default_styles::satelliteStreets.url)); - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - XCTAssertEqualObjects([MGLStyle emeraldStyleURL].absoluteString, @"mapbox://styles/mapbox/emerald-v8"); - XCTAssertEqualObjects([MGLStyle hybridStyleURL].absoluteString, @"mapbox://styles/mapbox/satellite-hybrid-v8"); -#pragma clang diagnostic pop } - (void)testVersionedStyleURLs { @@ -99,19 +94,8 @@ @(mbgl::util::default_styles::satelliteStreets.url)); XCTAssertEqualObjects([MGLStyle satelliteStreetsStyleURLWithVersion:99].absoluteString, @"mapbox://styles/mapbox/satellite-streets-v99"); -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - XCTAssertEqualObjects([MGLStyle trafficDayStyleURLWithVersion:mbgl::util::default_styles::trafficDay.currentVersion].absoluteString, - @(mbgl::util::default_styles::trafficDay.url)); - XCTAssertEqualObjects([MGLStyle trafficDayStyleURLWithVersion:99].absoluteString, - @"mapbox://styles/mapbox/traffic-day-v99"); - XCTAssertEqualObjects([MGLStyle trafficNightStyleURLWithVersion:mbgl::util::default_styles::trafficNight.currentVersion].absoluteString, - @(mbgl::util::default_styles::trafficNight.url)); - XCTAssertEqualObjects([MGLStyle trafficNightStyleURLWithVersion:99].absoluteString, - @"mapbox://styles/mapbox/traffic-night-v99"); -#pragma clang diagnostic pop - - static_assert(8 == mbgl::util::default_styles::numOrderedStyles, + + static_assert(6 == mbgl::util::default_styles::numOrderedStyles, "MGLStyleTests isn’t testing all the styles in mbgl::util::default_styles."); } @@ -143,7 +127,7 @@ NSString *styleHeader = self.stringWithContentsOfStyleHeader; NSError *versionedMethodError; - NSString *versionedMethodExpressionString = @(R"RE(^\+\s*\(NSURL\s*\*\s*\)\s*\w+StyleURLWithVersion\s*:\s*\(\s*NSInteger\s*\)\s*version\s*\b)RE"); + NSString *versionedMethodExpressionString = @(R"RE(^\+\s*\(NSURL\s*\*\s*\)\s*(?!traffic)\w+StyleURLWithVersion\s*:\s*\(\s*NSInteger\s*\)\s*version\s*\b)RE"); NSRegularExpression *versionedMethodExpression = [NSRegularExpression regularExpressionWithPattern:versionedMethodExpressionString options:NSRegularExpressionAnchorsMatchLines error:&versionedMethodError]; XCTAssertNil(versionedMethodError, @"Error compiling regular expression to search for versioned methods."); NSUInteger numVersionedMethodDeclarations = [versionedMethodExpression numberOfMatchesInString:styleHeader options:0 range:NSMakeRange(0, styleHeader.length)]; @@ -174,89 +158,89 @@ [self.style addSource:shapeSource]; XCTAssertThrowsSpecificNamed([self.style addSource:shapeSource], NSException, @"MGLRedundantSourceException"); - MGLRasterSource *rasterSource = [[MGLRasterSource alloc] initWithIdentifier:@"rasterSource" configurationURL:[NSURL URLWithString:@".json"] tileSize:42]; - [self.style addSource:rasterSource]; - XCTAssertThrowsSpecificNamed([self.style addSource:rasterSource], NSException, @"MGLRedundantSourceException"); + MGLRasterTileSource *rasterTileSource = [[MGLRasterTileSource alloc] initWithIdentifier:@"rasterTileSource" configurationURL:[NSURL URLWithString:@".json"] tileSize:42]; + [self.style addSource:rasterTileSource]; + XCTAssertThrowsSpecificNamed([self.style addSource:rasterTileSource], NSException, @"MGLRedundantSourceException"); - MGLVectorSource *vectorSource = [[MGLVectorSource alloc] initWithIdentifier:@"vectorSource" configurationURL:[NSURL URLWithString:@".json"]]; - [self.style addSource:vectorSource]; - XCTAssertThrowsSpecificNamed([self.style addSource:vectorSource], NSException, @"MGLRedundantSourceException"); + MGLVectorTileSource *vectorTileSource = [[MGLVectorTileSource alloc] initWithIdentifier:@"vectorTileSource" configurationURL:[NSURL URLWithString:@".json"]]; + [self.style addSource:vectorTileSource]; + XCTAssertThrowsSpecificNamed([self.style addSource:vectorTileSource], NSException, @"MGLRedundantSourceException"); } - (void)testAddingSourcesWithDuplicateIdentifiers { - MGLVectorSource *source1 = [[MGLVectorSource alloc] initWithIdentifier:@"my-source" configurationURL:[NSURL URLWithString:@"mapbox://mapbox.mapbox-terrain-v2"]]; - MGLVectorSource *source2 = [[MGLVectorSource alloc] initWithIdentifier:@"my-source" configurationURL:[NSURL URLWithString:@"mapbox://mapbox.mapbox-terrain-v2"]]; + MGLVectorTileSource *source1 = [[MGLVectorTileSource alloc] initWithIdentifier:@"my-source" configurationURL:[NSURL URLWithString:@"mapbox://mapbox.mapbox-terrain-v2"]]; + MGLVectorTileSource *source2 = [[MGLVectorTileSource alloc] initWithIdentifier:@"my-source" configurationURL:[NSURL URLWithString:@"mapbox://mapbox.mapbox-terrain-v2"]]; [self.style addSource: source1]; XCTAssertThrowsSpecificNamed([self.style addSource: source2], NSException, @"MGLRedundantSourceIdentifierException"); } - (void)testRemovingSourcesBeforeAddingThem { - MGLRasterSource *rasterSource = [[MGLRasterSource alloc] initWithIdentifier:@"raster-source" tileURLTemplates:@[] options:nil]; - [self.style removeSource:rasterSource]; - [self.style addSource:rasterSource]; - XCTAssertNotNil([self.style sourceWithIdentifier:rasterSource.identifier]); + MGLRasterTileSource *rasterTileSource = [[MGLRasterTileSource alloc] initWithIdentifier:@"raster-tile-source" tileURLTemplates:@[] options:nil]; + [self.style removeSource:rasterTileSource]; + [self.style addSource:rasterTileSource]; + XCTAssertNotNil([self.style sourceWithIdentifier:rasterTileSource.identifier]); MGLShapeSource *shapeSource = [[MGLShapeSource alloc] initWithIdentifier:@"shape-source" shape:nil options:nil]; [self.style removeSource:shapeSource]; [self.style addSource:shapeSource]; XCTAssertNotNil([self.style sourceWithIdentifier:shapeSource.identifier]); - MGLVectorSource *vectorSource = [[MGLVectorSource alloc] initWithIdentifier:@"vector-source" tileURLTemplates:@[] options:nil]; - [self.style removeSource:vectorSource]; - [self.style addSource:vectorSource]; - XCTAssertNotNil([self.style sourceWithIdentifier:vectorSource.identifier]); + MGLVectorTileSource *vectorTileSource = [[MGLVectorTileSource alloc] initWithIdentifier:@"vector-tile-source" tileURLTemplates:@[] options:nil]; + [self.style removeSource:vectorTileSource]; + [self.style addSource:vectorTileSource]; + XCTAssertNotNil([self.style sourceWithIdentifier:vectorTileSource.identifier]); } - (void)testAddingSourceOfTypeABeforeSourceOfTypeBWithSameIdentifier { - // Add a raster source - MGLRasterSource *rasterSource = [[MGLRasterSource alloc] initWithIdentifier:@"some-identifier" tileURLTemplates:@[] options:nil]; - [self.style addSource:rasterSource]; + // Add a raster tile source + MGLRasterTileSource *rasterTileSource = [[MGLRasterTileSource alloc] initWithIdentifier:@"some-identifier" tileURLTemplates:@[] options:nil]; + [self.style addSource:rasterTileSource]; - // Attempt to remove an image source with the same identifier as the raster source + // Attempt to remove an image source with the same identifier as the raster tile source MGLImageSource *imageSource = [[MGLImageSource alloc] initWithIdentifier:@"some-identifier" coordinateQuad: { } URL:[NSURL URLWithString:@"http://host/image.png"]]; [self.style removeSource:imageSource]; - // The raster source should still be added - XCTAssertTrue([[self.style sourceWithIdentifier:rasterSource.identifier] isMemberOfClass:[MGLRasterSource class]]); + // The raster tile source should still be added + XCTAssertTrue([[self.style sourceWithIdentifier:rasterTileSource.identifier] isMemberOfClass:[MGLRasterTileSource class]]); - // Remove the raster source - [self.style removeSource:rasterSource]; + // Remove the raster tile source + [self.style removeSource:rasterTileSource]; // Add the shape source [self.style addSource:imageSource]; - // Attempt to remove a vector source with the same identifer as the shape source - MGLVectorSource *vectorSource = [[MGLVectorSource alloc] initWithIdentifier:@"some-identifier" tileURLTemplates:@[] options:nil]; - [self.style removeSource:vectorSource]; + // Attempt to remove a vector tile source with the same identifer as the shape source + MGLVectorTileSource *vectorTileSource = [[MGLVectorTileSource alloc] initWithIdentifier:@"some-identifier" tileURLTemplates:@[] options:nil]; + [self.style removeSource:vectorTileSource]; // The image source should still be added XCTAssertTrue([[self.style sourceWithIdentifier:imageSource.identifier] isMemberOfClass:[MGLImageSource class]]); // Remove the image source [self.style removeSource:imageSource]; - // Add the vector source - [self.style addSource:vectorSource]; + // Add the vector tile source + [self.style addSource:vectorTileSource]; - // Attempt to remove the previously created raster source that has the same identifer as the shape source - [self.style removeSource:rasterSource]; - // The vector source should still be added - XCTAssertTrue([[self.style sourceWithIdentifier:imageSource.identifier] isMemberOfClass:[MGLVectorSource class]]); + // Attempt to remove the previously created raster tile source that has the same identifer as the shape source + [self.style removeSource:rasterTileSource]; + // The vector tile source should still be added + XCTAssertTrue([[self.style sourceWithIdentifier:imageSource.identifier] isMemberOfClass:[MGLVectorTileSource class]]); } - (void)testRemovingSourceInUse { - // Add a raster source - MGLRasterSource *rasterSource = [[MGLRasterSource alloc] initWithIdentifier:@"some-identifier" tileURLTemplates:@[] options:nil]; - [self.style addSource:rasterSource]; + // Add a raster tile source + MGLRasterTileSource *rasterTileSource = [[MGLRasterTileSource alloc] initWithIdentifier:@"some-identifier" tileURLTemplates:@[] options:nil]; + [self.style addSource:rasterTileSource]; // Add a layer using it - MGLFillStyleLayer *fillLayer = [[MGLFillStyleLayer alloc] initWithIdentifier:@"fillLayer" source:rasterSource]; + MGLFillStyleLayer *fillLayer = [[MGLFillStyleLayer alloc] initWithIdentifier:@"fillLayer" source:rasterTileSource]; [self.style addLayer:fillLayer]; - // Attempt to remove the raster source - [self.style removeSource:rasterSource]; + // Attempt to remove the raster tile source + [self.style removeSource:rasterTileSource]; // Ensure it is still there - XCTAssertTrue([[self.style sourceWithIdentifier:rasterSource.identifier] isMemberOfClass:[MGLRasterSource class]]); + XCTAssertTrue([[self.style sourceWithIdentifier:rasterTileSource.identifier] isMemberOfClass:[MGLRasterTileSource class]]); } - (void)testLayers { @@ -306,7 +290,7 @@ - (void)testAddingLayersWithDuplicateIdentifiers { // Just some source - MGLVectorSource *source = [[MGLVectorSource alloc] initWithIdentifier:@"my-source" configurationURL:[NSURL URLWithString:@"mapbox://mapbox.mapbox-terrain-v2"]]; + MGLVectorTileSource *source = [[MGLVectorTileSource alloc] initWithIdentifier:@"my-source" configurationURL:[NSURL URLWithString:@"mapbox://mapbox.mapbox-terrain-v2"]]; [self.style addSource: source]; // Add initial layer @@ -383,13 +367,6 @@ return styleHeader; } -- (void)testClasses { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - XCTAssertEqual(self.style.styleClasses.count, 0); -#pragma clang diagnostic pop -} - - (void)testImages { NSString *imageName = @"TrackingLocationMask"; #if TARGET_OS_IPHONE @@ -443,4 +420,45 @@ XCTAssertEqualObjects(layers[startIndex++].identifier, layer4.identifier); } +#pragma mark Localization tests + +- (void)testLanguageMatching { + { + NSArray *preferences = @[@"en"]; + XCTAssertEqualObjects([MGLVectorTileSource preferredMapboxStreetsLanguageForPreferences:preferences], @"en"); + } + { + NSArray *preferences = @[@"en-US"]; + XCTAssertEqualObjects([MGLVectorTileSource preferredMapboxStreetsLanguageForPreferences:preferences], @"en"); + } + { + NSArray *preferences = @[@"fr"]; + XCTAssertEqualObjects([MGLVectorTileSource preferredMapboxStreetsLanguageForPreferences:preferences], @"fr"); + } + { + NSArray *preferences = @[@"zh-Hans"]; + XCTAssertEqualObjects([MGLVectorTileSource preferredMapboxStreetsLanguageForPreferences:preferences], @"zh-Hans"); + } + { + NSArray *preferences = @[@"zh-Hans", @"en"]; + XCTAssertEqualObjects([MGLVectorTileSource preferredMapboxStreetsLanguageForPreferences:preferences], @"zh-Hans"); + } + { + NSArray *preferences = @[@"zh-Hant"]; + XCTAssertNil([MGLVectorTileSource preferredMapboxStreetsLanguageForPreferences:preferences]); + } + { + NSArray *preferences = @[@"tlh"]; + XCTAssertNil([MGLVectorTileSource preferredMapboxStreetsLanguageForPreferences:preferences]); + } + { + NSArray *preferences = @[@"tlh", @"en"]; + XCTAssertEqualObjects([MGLVectorTileSource preferredMapboxStreetsLanguageForPreferences:preferences], @"en"); + } + { + NSArray *preferences = @[@"mul"]; + XCTAssertNil([MGLVectorTileSource preferredMapboxStreetsLanguageForPreferences:preferences]); + } +} + @end diff --git a/platform/darwin/test/MGLSymbolStyleLayerTests.mm b/platform/darwin/test/MGLSymbolStyleLayerTests.mm index 05e091b5c8..cf2f80125a 100644 --- a/platform/darwin/test/MGLSymbolStyleLayerTests.mm +++ b/platform/darwin/test/MGLSymbolStyleLayerTests.mm @@ -30,8 +30,8 @@ XCTAssertNil(layer.sourceLayerIdentifier); XCTAssertNil(layer.predicate); - layer.predicate = [NSPredicate predicateWithValue:NO]; - XCTAssertEqualObjects(layer.predicate, [NSPredicate predicateWithValue:NO]); + layer.predicate = [NSPredicate predicateWithFormat:@"$featureIdentifier = 1"]; + XCTAssertEqualObjects(layer.predicate, [NSPredicate predicateWithFormat:@"$featureIdentifier = 1"]); layer.predicate = nil; XCTAssertNil(layer.predicate); } @@ -63,7 +63,7 @@ @"iconAllowsOverlap should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"true"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconAllowsOverlap = functionExpression; mbgl::style::IntervalStops<bool> intervalStops = {{ @@ -87,8 +87,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.iconAllowsOverlap = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.iconAllowsOverlap = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -107,7 +107,7 @@ @"iconAnchor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'bottom-right'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconAnchor = functionExpression; mbgl::style::IntervalStops<mbgl::style::SymbolAnchorType> intervalStops = {{ @@ -145,7 +145,7 @@ @"iconIgnoresPlacement should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"true"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconIgnoresPlacement = functionExpression; mbgl::style::IntervalStops<bool> intervalStops = {{ @@ -169,8 +169,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.iconIgnoresPlacement = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.iconIgnoresPlacement = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -189,7 +189,7 @@ @"iconImageName should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'Icon Image'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconImageName = functionExpression; mbgl::style::IntervalStops<std::string> intervalStops = {{ @@ -233,7 +233,7 @@ @"iconOffset should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"{1, 1}"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconOffset = functionExpression; mbgl::style::IntervalStops<std::array<float, 2>> intervalStops = {{ @@ -247,7 +247,7 @@ XCTAssertEqualObjects(layer.iconOffset, functionExpression, @"iconOffset should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.iconOffset = functionExpression; mbgl::style::ExponentialStops<std::array<float, 2>> exponentialStops = { {{18, { 1, 1 }}}, 1.0 }; @@ -255,10 +255,11 @@ XCTAssertEqual(rawLayer->getIconOffset(), propertyValue, @"Setting iconOffset to a data expression should update icon-offset."); - XCTAssertEqualObjects(layer.iconOffset, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.iconOffset, pedanticFunctionExpression, @"iconOffset should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.iconOffset = functionExpression; std::map<float, std::array<float, 2>> innerStops { {18, { 1, 1 }} }; @@ -268,7 +269,8 @@ XCTAssertEqual(rawLayer->getIconOffset(), propertyValue, @"Setting iconOffset to a camera-data expression should update icon-offset."); - XCTAssertEqualObjects(layer.iconOffset, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.iconOffset, pedanticFunctionExpression, @"iconOffset should round-trip camera-data expressions."); @@ -294,7 +296,7 @@ @"iconOptional should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"true"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconOptional = functionExpression; mbgl::style::IntervalStops<bool> intervalStops = {{ @@ -318,8 +320,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.iconOptional = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.iconOptional = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -338,7 +340,7 @@ @"iconPadding should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconPadding = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -362,8 +364,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.iconPadding = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.iconPadding = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -382,7 +384,7 @@ @"iconPitchAlignment should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'auto'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconPitchAlignment = functionExpression; mbgl::style::IntervalStops<mbgl::style::AlignmentType> intervalStops = {{ @@ -406,8 +408,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.iconPitchAlignment = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.iconPitchAlignment = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -426,7 +428,7 @@ @"iconRotation should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconRotation = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -440,7 +442,7 @@ XCTAssertEqualObjects(layer.iconRotation, functionExpression, @"iconRotation should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.iconRotation = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -448,10 +450,11 @@ XCTAssertEqual(rawLayer->getIconRotate(), propertyValue, @"Setting iconRotation to a data expression should update icon-rotate."); - XCTAssertEqualObjects(layer.iconRotation, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.iconRotation, pedanticFunctionExpression, @"iconRotation should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.iconRotation = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -461,7 +464,8 @@ XCTAssertEqual(rawLayer->getIconRotate(), propertyValue, @"Setting iconRotation to a camera-data expression should update icon-rotate."); - XCTAssertEqualObjects(layer.iconRotation, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.iconRotation, pedanticFunctionExpression, @"iconRotation should round-trip camera-data expressions."); @@ -487,7 +491,7 @@ @"iconRotationAlignment should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'auto'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconRotationAlignment = functionExpression; mbgl::style::IntervalStops<mbgl::style::AlignmentType> intervalStops = {{ @@ -511,8 +515,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.iconRotationAlignment = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.iconRotationAlignment = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -531,7 +535,7 @@ @"iconScale should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconScale = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -545,7 +549,7 @@ XCTAssertEqualObjects(layer.iconScale, functionExpression, @"iconScale should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.iconScale = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -553,10 +557,11 @@ XCTAssertEqual(rawLayer->getIconSize(), propertyValue, @"Setting iconScale to a data expression should update icon-size."); - XCTAssertEqualObjects(layer.iconScale, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.iconScale, pedanticFunctionExpression, @"iconScale should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.iconScale = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -566,7 +571,8 @@ XCTAssertEqual(rawLayer->getIconSize(), propertyValue, @"Setting iconScale to a camera-data expression should update icon-size."); - XCTAssertEqualObjects(layer.iconScale, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.iconScale, pedanticFunctionExpression, @"iconScale should round-trip camera-data expressions."); @@ -592,7 +598,7 @@ @"iconTextFit should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'both'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconTextFit = functionExpression; mbgl::style::IntervalStops<mbgl::style::IconTextFitType> intervalStops = {{ @@ -616,8 +622,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.iconTextFit = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.iconTextFit = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -642,7 +648,7 @@ @"iconTextFitPadding should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"{1, 1, 1, 1}"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconTextFitPadding = functionExpression; mbgl::style::IntervalStops<std::array<float, 4>> intervalStops = {{ @@ -666,8 +672,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.iconTextFitPadding = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.iconTextFitPadding = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -686,7 +692,7 @@ @"keepsIconUpright should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"true"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.keepsIconUpright = functionExpression; mbgl::style::IntervalStops<bool> intervalStops = {{ @@ -710,8 +716,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.keepsIconUpright = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.keepsIconUpright = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -730,7 +736,7 @@ @"keepsTextUpright should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"false"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.keepsTextUpright = functionExpression; mbgl::style::IntervalStops<bool> intervalStops = {{ @@ -754,8 +760,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.keepsTextUpright = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.keepsTextUpright = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -774,7 +780,7 @@ @"maximumTextAngle should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.maximumTextAngle = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -798,8 +804,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.maximumTextAngle = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.maximumTextAngle = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -818,7 +824,7 @@ @"maximumTextWidth should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.maximumTextWidth = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -832,7 +838,7 @@ XCTAssertEqualObjects(layer.maximumTextWidth, functionExpression, @"maximumTextWidth should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.maximumTextWidth = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -840,10 +846,11 @@ XCTAssertEqual(rawLayer->getTextMaxWidth(), propertyValue, @"Setting maximumTextWidth to a data expression should update text-max-width."); - XCTAssertEqualObjects(layer.maximumTextWidth, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.maximumTextWidth, pedanticFunctionExpression, @"maximumTextWidth should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.maximumTextWidth = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -853,7 +860,8 @@ XCTAssertEqual(rawLayer->getTextMaxWidth(), propertyValue, @"Setting maximumTextWidth to a camera-data expression should update text-max-width."); - XCTAssertEqualObjects(layer.maximumTextWidth, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.maximumTextWidth, pedanticFunctionExpression, @"maximumTextWidth should round-trip camera-data expressions."); @@ -879,7 +887,7 @@ @"symbolAvoidsEdges should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"true"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.symbolAvoidsEdges = functionExpression; mbgl::style::IntervalStops<bool> intervalStops = {{ @@ -903,8 +911,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.symbolAvoidsEdges = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.symbolAvoidsEdges = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -923,7 +931,7 @@ @"symbolPlacement should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'line'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.symbolPlacement = functionExpression; mbgl::style::IntervalStops<mbgl::style::SymbolPlacementType> intervalStops = {{ @@ -947,8 +955,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.symbolPlacement = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.symbolPlacement = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -967,7 +975,7 @@ @"symbolSpacing should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.symbolSpacing = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -991,8 +999,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.symbolSpacing = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.symbolSpacing = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -1011,7 +1019,7 @@ @"text should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'Text Field'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.text = functionExpression; mbgl::style::IntervalStops<std::string> intervalStops = {{ @@ -1049,7 +1057,7 @@ @"textAllowsOverlap should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"true"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textAllowsOverlap = functionExpression; mbgl::style::IntervalStops<bool> intervalStops = {{ @@ -1073,8 +1081,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.textAllowsOverlap = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.textAllowsOverlap = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -1093,7 +1101,7 @@ @"textAnchor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'bottom-right'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textAnchor = functionExpression; mbgl::style::IntervalStops<mbgl::style::SymbolAnchorType> intervalStops = {{ @@ -1131,7 +1139,7 @@ @"textFontNames should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"{'Text Font', 'Tnof Txet'}"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textFontNames = functionExpression; mbgl::style::IntervalStops<std::vector<std::string>> intervalStops = {{ @@ -1169,7 +1177,7 @@ @"textFontSize should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textFontSize = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -1183,7 +1191,7 @@ XCTAssertEqualObjects(layer.textFontSize, functionExpression, @"textFontSize should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.textFontSize = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -1191,10 +1199,11 @@ XCTAssertEqual(rawLayer->getTextSize(), propertyValue, @"Setting textFontSize to a data expression should update text-size."); - XCTAssertEqualObjects(layer.textFontSize, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.textFontSize, pedanticFunctionExpression, @"textFontSize should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.textFontSize = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -1204,7 +1213,8 @@ XCTAssertEqual(rawLayer->getTextSize(), propertyValue, @"Setting textFontSize to a camera-data expression should update text-size."); - XCTAssertEqualObjects(layer.textFontSize, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.textFontSize, pedanticFunctionExpression, @"textFontSize should round-trip camera-data expressions."); @@ -1230,7 +1240,7 @@ @"textIgnoresPlacement should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"true"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textIgnoresPlacement = functionExpression; mbgl::style::IntervalStops<bool> intervalStops = {{ @@ -1254,8 +1264,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.textIgnoresPlacement = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.textIgnoresPlacement = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -1274,7 +1284,7 @@ @"textJustification should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'right'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textJustification = functionExpression; mbgl::style::IntervalStops<mbgl::style::TextJustifyType> intervalStops = {{ @@ -1312,7 +1322,7 @@ @"textLetterSpacing should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textLetterSpacing = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -1326,7 +1336,7 @@ XCTAssertEqualObjects(layer.textLetterSpacing, functionExpression, @"textLetterSpacing should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.textLetterSpacing = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -1334,10 +1344,11 @@ XCTAssertEqual(rawLayer->getTextLetterSpacing(), propertyValue, @"Setting textLetterSpacing to a data expression should update text-letter-spacing."); - XCTAssertEqualObjects(layer.textLetterSpacing, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.textLetterSpacing, pedanticFunctionExpression, @"textLetterSpacing should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.textLetterSpacing = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -1347,7 +1358,8 @@ XCTAssertEqual(rawLayer->getTextLetterSpacing(), propertyValue, @"Setting textLetterSpacing to a camera-data expression should update text-letter-spacing."); - XCTAssertEqualObjects(layer.textLetterSpacing, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.textLetterSpacing, pedanticFunctionExpression, @"textLetterSpacing should round-trip camera-data expressions."); @@ -1373,7 +1385,7 @@ @"textLineHeight should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textLineHeight = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -1397,8 +1409,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.textLineHeight = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.textLineHeight = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -1423,7 +1435,7 @@ @"textOffset should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"{1, 1}"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textOffset = functionExpression; mbgl::style::IntervalStops<std::array<float, 2>> intervalStops = {{ @@ -1437,7 +1449,7 @@ XCTAssertEqualObjects(layer.textOffset, functionExpression, @"textOffset should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.textOffset = functionExpression; mbgl::style::ExponentialStops<std::array<float, 2>> exponentialStops = { {{18, { 1, 1 }}}, 1.0 }; @@ -1445,10 +1457,11 @@ XCTAssertEqual(rawLayer->getTextOffset(), propertyValue, @"Setting textOffset to a data expression should update text-offset."); - XCTAssertEqualObjects(layer.textOffset, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.textOffset, pedanticFunctionExpression, @"textOffset should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.textOffset = functionExpression; std::map<float, std::array<float, 2>> innerStops { {18, { 1, 1 }} }; @@ -1458,7 +1471,8 @@ XCTAssertEqual(rawLayer->getTextOffset(), propertyValue, @"Setting textOffset to a camera-data expression should update text-offset."); - XCTAssertEqualObjects(layer.textOffset, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.textOffset, pedanticFunctionExpression, @"textOffset should round-trip camera-data expressions."); @@ -1484,7 +1498,7 @@ @"textOptional should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"true"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textOptional = functionExpression; mbgl::style::IntervalStops<bool> intervalStops = {{ @@ -1508,8 +1522,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.textOptional = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.textOptional = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -1528,7 +1542,7 @@ @"textPadding should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textPadding = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -1552,8 +1566,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.textPadding = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.textPadding = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -1572,7 +1586,7 @@ @"textPitchAlignment should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'auto'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textPitchAlignment = functionExpression; mbgl::style::IntervalStops<mbgl::style::AlignmentType> intervalStops = {{ @@ -1596,8 +1610,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.textPitchAlignment = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.textPitchAlignment = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -1616,7 +1630,7 @@ @"textRotation should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textRotation = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -1630,7 +1644,7 @@ XCTAssertEqualObjects(layer.textRotation, functionExpression, @"textRotation should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.textRotation = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -1638,10 +1652,11 @@ XCTAssertEqual(rawLayer->getTextRotate(), propertyValue, @"Setting textRotation to a data expression should update text-rotate."); - XCTAssertEqualObjects(layer.textRotation, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.textRotation, pedanticFunctionExpression, @"textRotation should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.textRotation = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -1651,7 +1666,8 @@ XCTAssertEqual(rawLayer->getTextRotate(), propertyValue, @"Setting textRotation to a camera-data expression should update text-rotate."); - XCTAssertEqualObjects(layer.textRotation, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.textRotation, pedanticFunctionExpression, @"textRotation should round-trip camera-data expressions."); @@ -1677,7 +1693,7 @@ @"textRotationAlignment should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'auto'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textRotationAlignment = functionExpression; mbgl::style::IntervalStops<mbgl::style::AlignmentType> intervalStops = {{ @@ -1701,8 +1717,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.textRotationAlignment = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.textRotationAlignment = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -1721,7 +1737,7 @@ @"textTransform should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'lowercase'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textTransform = functionExpression; mbgl::style::IntervalStops<mbgl::style::TextTransformType> intervalStops = {{ @@ -1759,7 +1775,7 @@ @"iconColor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"%@", [MGLColor redColor]]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconColor = functionExpression; mbgl::style::IntervalStops<mbgl::Color> intervalStops = {{ @@ -1773,7 +1789,7 @@ XCTAssertEqualObjects(layer.iconColor, functionExpression, @"iconColor should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.iconColor = functionExpression; mbgl::style::ExponentialStops<mbgl::Color> exponentialStops = { {{18, { 1, 0, 0, 1 }}}, 1.0 }; @@ -1781,10 +1797,11 @@ XCTAssertEqual(rawLayer->getIconColor(), propertyValue, @"Setting iconColor to a data expression should update icon-color."); - XCTAssertEqualObjects(layer.iconColor, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.iconColor, pedanticFunctionExpression, @"iconColor should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.iconColor = functionExpression; std::map<float, mbgl::Color> innerStops { {18, { 1, 0, 0, 1 }} }; @@ -1794,7 +1811,8 @@ XCTAssertEqual(rawLayer->getIconColor(), propertyValue, @"Setting iconColor to a camera-data expression should update icon-color."); - XCTAssertEqualObjects(layer.iconColor, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.iconColor, pedanticFunctionExpression, @"iconColor should round-trip camera-data expressions."); @@ -1829,7 +1847,7 @@ @"iconHaloBlur should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconHaloBlur = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -1843,7 +1861,7 @@ XCTAssertEqualObjects(layer.iconHaloBlur, functionExpression, @"iconHaloBlur should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.iconHaloBlur = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -1851,10 +1869,11 @@ XCTAssertEqual(rawLayer->getIconHaloBlur(), propertyValue, @"Setting iconHaloBlur to a data expression should update icon-halo-blur."); - XCTAssertEqualObjects(layer.iconHaloBlur, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.iconHaloBlur, pedanticFunctionExpression, @"iconHaloBlur should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.iconHaloBlur = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -1864,7 +1883,8 @@ XCTAssertEqual(rawLayer->getIconHaloBlur(), propertyValue, @"Setting iconHaloBlur to a camera-data expression should update icon-halo-blur."); - XCTAssertEqualObjects(layer.iconHaloBlur, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.iconHaloBlur, pedanticFunctionExpression, @"iconHaloBlur should round-trip camera-data expressions."); @@ -1899,7 +1919,7 @@ @"iconHaloColor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"%@", [MGLColor redColor]]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconHaloColor = functionExpression; mbgl::style::IntervalStops<mbgl::Color> intervalStops = {{ @@ -1913,7 +1933,7 @@ XCTAssertEqualObjects(layer.iconHaloColor, functionExpression, @"iconHaloColor should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.iconHaloColor = functionExpression; mbgl::style::ExponentialStops<mbgl::Color> exponentialStops = { {{18, { 1, 0, 0, 1 }}}, 1.0 }; @@ -1921,10 +1941,11 @@ XCTAssertEqual(rawLayer->getIconHaloColor(), propertyValue, @"Setting iconHaloColor to a data expression should update icon-halo-color."); - XCTAssertEqualObjects(layer.iconHaloColor, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.iconHaloColor, pedanticFunctionExpression, @"iconHaloColor should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.iconHaloColor = functionExpression; std::map<float, mbgl::Color> innerStops { {18, { 1, 0, 0, 1 }} }; @@ -1934,7 +1955,8 @@ XCTAssertEqual(rawLayer->getIconHaloColor(), propertyValue, @"Setting iconHaloColor to a camera-data expression should update icon-halo-color."); - XCTAssertEqualObjects(layer.iconHaloColor, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.iconHaloColor, pedanticFunctionExpression, @"iconHaloColor should round-trip camera-data expressions."); @@ -1969,7 +1991,7 @@ @"iconHaloWidth should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconHaloWidth = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -1983,7 +2005,7 @@ XCTAssertEqualObjects(layer.iconHaloWidth, functionExpression, @"iconHaloWidth should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.iconHaloWidth = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -1991,10 +2013,11 @@ XCTAssertEqual(rawLayer->getIconHaloWidth(), propertyValue, @"Setting iconHaloWidth to a data expression should update icon-halo-width."); - XCTAssertEqualObjects(layer.iconHaloWidth, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.iconHaloWidth, pedanticFunctionExpression, @"iconHaloWidth should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.iconHaloWidth = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -2004,7 +2027,8 @@ XCTAssertEqual(rawLayer->getIconHaloWidth(), propertyValue, @"Setting iconHaloWidth to a camera-data expression should update icon-halo-width."); - XCTAssertEqualObjects(layer.iconHaloWidth, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.iconHaloWidth, pedanticFunctionExpression, @"iconHaloWidth should round-trip camera-data expressions."); @@ -2039,7 +2063,7 @@ @"iconOpacity should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconOpacity = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -2053,7 +2077,7 @@ XCTAssertEqualObjects(layer.iconOpacity, functionExpression, @"iconOpacity should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.iconOpacity = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -2061,10 +2085,11 @@ XCTAssertEqual(rawLayer->getIconOpacity(), propertyValue, @"Setting iconOpacity to a data expression should update icon-opacity."); - XCTAssertEqualObjects(layer.iconOpacity, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.iconOpacity, pedanticFunctionExpression, @"iconOpacity should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.iconOpacity = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -2074,7 +2099,8 @@ XCTAssertEqual(rawLayer->getIconOpacity(), propertyValue, @"Setting iconOpacity to a camera-data expression should update icon-opacity."); - XCTAssertEqualObjects(layer.iconOpacity, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.iconOpacity, pedanticFunctionExpression, @"iconOpacity should round-trip camera-data expressions."); @@ -2115,7 +2141,7 @@ @"iconTranslation should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"{1, 1}"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconTranslation = functionExpression; mbgl::style::IntervalStops<std::array<float, 2>> intervalStops = {{ @@ -2139,8 +2165,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.iconTranslation = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.iconTranslation = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -2159,7 +2185,7 @@ @"iconTranslationAnchor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'viewport'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.iconTranslationAnchor = functionExpression; mbgl::style::IntervalStops<mbgl::style::TranslateAnchorType> intervalStops = {{ @@ -2183,8 +2209,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.iconTranslationAnchor = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.iconTranslationAnchor = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -2203,7 +2229,7 @@ @"textColor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"%@", [MGLColor redColor]]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textColor = functionExpression; mbgl::style::IntervalStops<mbgl::Color> intervalStops = {{ @@ -2217,7 +2243,7 @@ XCTAssertEqualObjects(layer.textColor, functionExpression, @"textColor should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.textColor = functionExpression; mbgl::style::ExponentialStops<mbgl::Color> exponentialStops = { {{18, { 1, 0, 0, 1 }}}, 1.0 }; @@ -2225,10 +2251,11 @@ XCTAssertEqual(rawLayer->getTextColor(), propertyValue, @"Setting textColor to a data expression should update text-color."); - XCTAssertEqualObjects(layer.textColor, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.textColor, pedanticFunctionExpression, @"textColor should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.textColor = functionExpression; std::map<float, mbgl::Color> innerStops { {18, { 1, 0, 0, 1 }} }; @@ -2238,7 +2265,8 @@ XCTAssertEqual(rawLayer->getTextColor(), propertyValue, @"Setting textColor to a camera-data expression should update text-color."); - XCTAssertEqualObjects(layer.textColor, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.textColor, pedanticFunctionExpression, @"textColor should round-trip camera-data expressions."); @@ -2273,7 +2301,7 @@ @"textHaloBlur should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textHaloBlur = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -2287,7 +2315,7 @@ XCTAssertEqualObjects(layer.textHaloBlur, functionExpression, @"textHaloBlur should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.textHaloBlur = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -2295,10 +2323,11 @@ XCTAssertEqual(rawLayer->getTextHaloBlur(), propertyValue, @"Setting textHaloBlur to a data expression should update text-halo-blur."); - XCTAssertEqualObjects(layer.textHaloBlur, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.textHaloBlur, pedanticFunctionExpression, @"textHaloBlur should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.textHaloBlur = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -2308,7 +2337,8 @@ XCTAssertEqual(rawLayer->getTextHaloBlur(), propertyValue, @"Setting textHaloBlur to a camera-data expression should update text-halo-blur."); - XCTAssertEqualObjects(layer.textHaloBlur, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.textHaloBlur, pedanticFunctionExpression, @"textHaloBlur should round-trip camera-data expressions."); @@ -2343,7 +2373,7 @@ @"textHaloColor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"%@", [MGLColor redColor]]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textHaloColor = functionExpression; mbgl::style::IntervalStops<mbgl::Color> intervalStops = {{ @@ -2357,7 +2387,7 @@ XCTAssertEqualObjects(layer.textHaloColor, functionExpression, @"textHaloColor should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.textHaloColor = functionExpression; mbgl::style::ExponentialStops<mbgl::Color> exponentialStops = { {{18, { 1, 0, 0, 1 }}}, 1.0 }; @@ -2365,10 +2395,11 @@ XCTAssertEqual(rawLayer->getTextHaloColor(), propertyValue, @"Setting textHaloColor to a data expression should update text-halo-color."); - XCTAssertEqualObjects(layer.textHaloColor, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.textHaloColor, pedanticFunctionExpression, @"textHaloColor should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.textHaloColor = functionExpression; std::map<float, mbgl::Color> innerStops { {18, { 1, 0, 0, 1 }} }; @@ -2378,7 +2409,8 @@ XCTAssertEqual(rawLayer->getTextHaloColor(), propertyValue, @"Setting textHaloColor to a camera-data expression should update text-halo-color."); - XCTAssertEqualObjects(layer.textHaloColor, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.textHaloColor, pedanticFunctionExpression, @"textHaloColor should round-trip camera-data expressions."); @@ -2413,7 +2445,7 @@ @"textHaloWidth should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textHaloWidth = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -2427,7 +2459,7 @@ XCTAssertEqualObjects(layer.textHaloWidth, functionExpression, @"textHaloWidth should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.textHaloWidth = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -2435,10 +2467,11 @@ XCTAssertEqual(rawLayer->getTextHaloWidth(), propertyValue, @"Setting textHaloWidth to a data expression should update text-halo-width."); - XCTAssertEqualObjects(layer.textHaloWidth, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.textHaloWidth, pedanticFunctionExpression, @"textHaloWidth should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.textHaloWidth = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -2448,7 +2481,8 @@ XCTAssertEqual(rawLayer->getTextHaloWidth(), propertyValue, @"Setting textHaloWidth to a camera-data expression should update text-halo-width."); - XCTAssertEqualObjects(layer.textHaloWidth, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.textHaloWidth, pedanticFunctionExpression, @"textHaloWidth should round-trip camera-data expressions."); @@ -2483,7 +2517,7 @@ @"textOpacity should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"0xff"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textOpacity = functionExpression; mbgl::style::IntervalStops<float> intervalStops = {{ @@ -2497,7 +2531,7 @@ XCTAssertEqualObjects(layer.textOpacity, functionExpression, @"textOpacity should round-trip camera expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(keyName, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(keyName, 'linear', nil, %@)", @{@18: constantExpression}]; layer.textOpacity = functionExpression; mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; @@ -2505,10 +2539,11 @@ XCTAssertEqual(rawLayer->getTextOpacity(), propertyValue, @"Setting textOpacity to a data expression should update text-opacity."); - XCTAssertEqualObjects(layer.textOpacity, functionExpression, + NSExpression *pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:(CAST(keyName, 'NSNumber'), 'linear', nil, %@)", @{@18: constantExpression}]; + XCTAssertEqualObjects(layer.textOpacity, pedanticFunctionExpression, @"textOpacity should round-trip data expressions."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; layer.textOpacity = functionExpression; std::map<float, float> innerStops { {18, 0xff} }; @@ -2518,7 +2553,8 @@ XCTAssertEqual(rawLayer->getTextOpacity(), propertyValue, @"Setting textOpacity to a camera-data expression should update text-opacity."); - XCTAssertEqualObjects(layer.textOpacity, functionExpression, + pedanticFunctionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: pedanticFunctionExpression}]; + XCTAssertEqualObjects(layer.textOpacity, pedanticFunctionExpression, @"textOpacity should round-trip camera-data expressions."); @@ -2559,7 +2595,7 @@ @"textTranslation should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"{1, 1}"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textTranslation = functionExpression; mbgl::style::IntervalStops<std::array<float, 2>> intervalStops = {{ @@ -2583,8 +2619,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.textTranslation = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.textTranslation = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } @@ -2603,7 +2639,7 @@ @"textTranslationAnchor should round-trip constant value expressions."); constantExpression = [NSExpression expressionWithFormat:@"'viewport'"]; - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; + NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}]; layer.textTranslationAnchor = functionExpression; mbgl::style::IntervalStops<mbgl::style::TranslateAnchorType> intervalStops = {{ @@ -2627,8 +2663,8 @@ functionExpression = [NSExpression expressionForKeyPath:@"bogus"]; XCTAssertThrowsSpecificNamed(layer.textTranslationAnchor = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION(bogus, 'mgl_stepWithMinimum:stops:', %@, %@)", constantExpression, @{@18: constantExpression}]; - functionExpression = [NSExpression expressionWithFormat:@"FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', nil, %@)", @{@10: functionExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:(bogus, %@, %@)", constantExpression, @{@18: constantExpression}]; + functionExpression = [NSExpression expressionWithFormat:@"mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", @{@10: functionExpression}]; XCTAssertThrowsSpecificNamed(layer.textTranslationAnchor = functionExpression, NSException, NSInvalidArgumentException, @"MGLSymbolLayer should raise an exception if a camera-data expression is applied to a property that does not support key paths to feature attributes."); } } diff --git a/platform/darwin/test/MGLTileSetTests.mm b/platform/darwin/test/MGLTileSetTests.mm index 74c84184e1..2319f66447 100644 --- a/platform/darwin/test/MGLTileSetTests.mm +++ b/platform/darwin/test/MGLTileSetTests.mm @@ -66,8 +66,16 @@ // when the tile set has attribution infos MGLAttributionInfo *mapboxInfo = [[MGLAttributionInfo alloc] initWithTitle:[[NSAttributedString alloc] initWithString:@"Mapbox"] URL:[NSURL URLWithString:@"https://www.mapbox.com/"]]; +#if TARGET_OS_IPHONE + UIColor *redColor = [UIColor redColor]; +#else + // CSS uses the sRGB color space. In macOS 10.12 Sierra and below, + // -[NSColor redColor] is in the calibrated RGB space and has a slightly + // different sRGB value than on iOS and macOS 10.13 High Sierra. + NSColor *redColor = [NSColor colorWithSRGBRed:1 green:0 blue:0 alpha:1]; +#endif NSAttributedString *gl = [[NSAttributedString alloc] initWithString:@"GL" attributes:@{ - NSBackgroundColorAttributeName: [MGLColor redColor], + NSBackgroundColorAttributeName: redColor, }]; MGLAttributionInfo *glInfo = [[MGLAttributionInfo alloc] initWithTitle:gl URL:nil]; tileSet = MGLTileSetFromTileURLTemplates(tileURLTemplates, @{ @@ -82,7 +90,7 @@ #else NSString *html = (@"<font face=\"Helvetica\" size=\"3\" style=\"font: 12.0px Helvetica\">" @"<a href=\"https://www.mapbox.com/\">Mapbox</a> </font>" - @"<font face=\"Helvetica\" size=\"3\" style=\"font: 12.0px Helvetica; background-color: #ff2600\">GL</font>\n"); + @"<font face=\"Helvetica\" size=\"3\" style=\"font: 12.0px Helvetica; background-color: #ff0000\">GL</font>\n"); #endif XCTAssertEqualObjects(@(tileSet.attribution.c_str()), html); |