diff options
Diffstat (limited to 'platform/darwin/test')
-rw-r--r-- | platform/darwin/test/MGLAttributionInfoTests.m | 2 | ||||
-rw-r--r-- | platform/darwin/test/MGLDocumentationExampleTests.swift | 16 | ||||
-rw-r--r-- | platform/darwin/test/MGLDocumentationGuideTests.swift | 214 | ||||
-rw-r--r-- | platform/darwin/test/MGLFillExtrusionStyleLayerTests.mm | 445 | ||||
-rw-r--r-- | platform/darwin/test/MGLSDKTestHelpers.swift | 47 | ||||
-rw-r--r-- | platform/darwin/test/MGLShapeSourceTests.mm | 104 | ||||
-rw-r--r-- | platform/darwin/test/MGLSourceQueryTests.m | 60 | ||||
-rw-r--r-- | platform/darwin/test/MGLStyleLayerTests.mm.ejs | 2 | ||||
-rw-r--r-- | platform/darwin/test/MGLStyleTests.mm | 77 | ||||
-rw-r--r-- | platform/darwin/test/MGLSymbolStyleLayerTests.mm | 127 | ||||
-rw-r--r-- | platform/darwin/test/query-style.json | 98 |
11 files changed, 925 insertions, 267 deletions
diff --git a/platform/darwin/test/MGLAttributionInfoTests.m b/platform/darwin/test/MGLAttributionInfoTests.m index 74859bda82..e258671c09 100644 --- a/platform/darwin/test/MGLAttributionInfoTests.m +++ b/platform/darwin/test/MGLAttributionInfoTests.m @@ -68,7 +68,7 @@ XCTAssertEqual(infos.count, 1); XCTAssertEqualObjects(infos[0].title.string, @"Mapbox"); - XCTAssertEqualObjects([infos[0].title attribute:NSLinkAttributeName atIndex:0 effectiveRange:nil], [NSURL URLWithString:@"https://www.mapbox.com/"]); + XCTAssertNil([infos[0].title attribute:NSLinkAttributeName atIndex:0 effectiveRange:nil]); XCTAssertEqualObjects([infos[0].title attribute:NSUnderlineStyleAttributeName atIndex:0 effectiveRange:nil], @(NSUnderlineStyleSingle)); #if TARGET_OS_IPHONE diff --git a/platform/darwin/test/MGLDocumentationExampleTests.swift b/platform/darwin/test/MGLDocumentationExampleTests.swift index 177d97d523..6d2dc597a9 100644 --- a/platform/darwin/test/MGLDocumentationExampleTests.swift +++ b/platform/darwin/test/MGLDocumentationExampleTests.swift @@ -158,6 +158,22 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate { XCTAssertNotNil(mapView.style?.layer(withIdentifier: "parks")) } + + func testMGLFillExtrusionStyleLayer() { + let buildings = MGLVectorSource(identifier: "buildings", configurationURL: URL(string: "https://example.com/style.json")!) + mapView.style?.addSource(buildings) + + //#-example-code + let layer = MGLFillExtrusionStyleLayer(identifier: "buildings", source: buildings) + layer.sourceLayerIdentifier = "building" + layer.fillExtrusionHeight = MGLStyleValue(interpolationMode: .identity, sourceStops: nil, attributeName: "height", options: nil) + layer.fillExtrusionBase = MGLStyleValue(interpolationMode: .identity, sourceStops: nil, attributeName: "min_height", options: nil) + layer.predicate = NSPredicate(format: "extrude == TRUE") + mapView.style?.addLayer(layer) + //#-end-example-code + + XCTAssertNotNil(mapView.style?.layer(withIdentifier: "buildings")) + } func testMGLSymbolStyleLayer() { let pois = MGLVectorSource(identifier: "pois", configurationURL: URL(string: "https://example.com/style.json")!) diff --git a/platform/darwin/test/MGLDocumentationGuideTests.swift b/platform/darwin/test/MGLDocumentationGuideTests.swift new file mode 100644 index 0000000000..c71f1b46c7 --- /dev/null +++ b/platform/darwin/test/MGLDocumentationGuideTests.swift @@ -0,0 +1,214 @@ +import Foundation +import Mapbox +#if os(iOS) + import UIKit +#else + import Cocoa +#endif + +/** + Test cases that ensure the inline examples in the jazzy guides compile. + + To add an example: + 1. Add a test case named in the form `testGuideName$ExampleName`. + 2. Wrap the code you’d like to appear in the documentation within the + following comment blocks: + ``` + //#-example-code + ... + //#-end-example-code + ``` + 3. Insert a call to `guideExample()` where you’d like the example code to be + inserted in the guide’s Markdown. + ``` + <%- guideExample('GuideName', 'ExampleName', 'iOS') %> + ``` + 4. Run `make darwin-style-code` to extract example code from the test method + below and insert it into the guide. + */ +class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate { + var mapView: MGLMapView! + var styleLoadingExpectation: XCTestExpectation! + + override func setUp() { + super.setUp() + let styleURL = Bundle(for: MGLDocumentationGuideTests.self).url(forResource: "one-liner", withExtension: "json") + mapView = MGLMapView(frame: CGRect(x: 0, y: 0, width: 256, height: 256), styleURL: styleURL) + mapView.delegate = self + styleLoadingExpectation = expectation(description: "Map view should finish loading style") + waitForExpectations(timeout: 1, handler: nil) + } + + override func tearDown() { + mapView = nil + styleLoadingExpectation = nil + super.tearDown() + } + + func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) { + styleLoadingExpectation.fulfill() + } + + func testUsingStyleFunctionsAtRuntime$Stops() { + //#-example-code + #if os(macOS) + let stops = [ + 0: MGLStyleValue<NSColor>(rawValue: .yellow), + 2.5: MGLStyleValue(rawValue: .orange), + 5: MGLStyleValue(rawValue: .red), + 7.5: MGLStyleValue(rawValue: .blue), + 10: MGLStyleValue(rawValue: .white), + ] + #else + let stops = [ + 0: MGLStyleValue<UIColor>(rawValue: .yellow), + 2.5: MGLStyleValue(rawValue: .orange), + 5: MGLStyleValue(rawValue: .red), + 7.5: MGLStyleValue(rawValue: .blue), + 10: MGLStyleValue(rawValue: .white), + ] + #endif + //#-end-example-code + + let _ = MGLStyleValue(interpolationMode: .exponential, cameraStops: stops, options: nil) + } + + func testUsingStyleFunctionsAtRuntime$Linear() { + //#-example-code + let url = URL(string: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson")! + let symbolSource = MGLSource(identifier: "source") + let symbolLayer = MGLSymbolStyleLayer(identifier: "place-city-sm", source: symbolSource) + + let source = MGLShapeSource(identifier: "earthquakes", url: url, options: nil) + mapView.style?.addSource(source) + + #if os(macOS) + let stops = [ + 0: MGLStyleValue<NSColor>(rawValue: .yellow), + 2.5: MGLStyleValue(rawValue: .orange), + 5: MGLStyleValue(rawValue: .red), + 7.5: MGLStyleValue(rawValue: .blue), + 10: MGLStyleValue(rawValue: .white), + ] + #else + let stops = [ + 0: MGLStyleValue<UIColor>(rawValue: .yellow), + 2.5: MGLStyleValue(rawValue: .orange), + 5: MGLStyleValue(rawValue: .red), + 7.5: MGLStyleValue(rawValue: .blue), + 10: MGLStyleValue(rawValue: .white), + ] + #endif + + let layer = MGLCircleStyleLayer(identifier: "circles", source: source) + #if os(macOS) + layer.circleColor = MGLStyleValue(interpolationMode: .exponential, + sourceStops: stops, + attributeName: "mag", + options: [.defaultValue: MGLStyleValue<NSColor>(rawValue: .green)]) + #else + layer.circleColor = MGLStyleValue(interpolationMode: .exponential, + sourceStops: stops, + attributeName: "mag", + options: [.defaultValue: MGLStyleValue<UIColor>(rawValue: .green)]) + #endif + layer.circleRadius = MGLStyleValue(rawValue: 10) + mapView.style?.insertLayer(layer, below: symbolLayer) + //#-end-example-code + } + + func testUsingStyleFunctionsAtRuntime$Exponential() { + let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil) + let layer = MGLCircleStyleLayer(identifier: "circles", source: source) + + //#-example-code + let stops = [ + 12: MGLStyleValue<NSNumber>(rawValue: 0.5), + 14: MGLStyleValue(rawValue: 2), + 18: MGLStyleValue(rawValue: 18), + ] + + layer.circleRadius = MGLStyleValue(interpolationMode: .exponential, + cameraStops: stops, + options: [.interpolationBase: 1.5]) + //#-end-example-code + } + + func testUsingStyleFunctionsAtRuntime$Interval() { + let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil) + let layer = MGLCircleStyleLayer(identifier: "circles", source: source) + + //#-example-code + #if os(macOS) + let stops = [ + 0: MGLStyleValue<NSColor>(rawValue: .yellow), + 2.5: MGLStyleValue(rawValue: .orange), + 5: MGLStyleValue(rawValue: .red), + 7.5: MGLStyleValue(rawValue: .blue), + 10: MGLStyleValue(rawValue: .white), + ] + + layer.circleColor = MGLStyleValue(interpolationMode: .interval, + sourceStops: stops, + attributeName: "mag", + options: [.defaultValue: MGLStyleValue<NSColor>(rawValue: .green)]) + #else + let stops = [ + 0: MGLStyleValue<UIColor>(rawValue: .yellow), + 2.5: MGLStyleValue(rawValue: .orange), + 5: MGLStyleValue(rawValue: .red), + 7.5: MGLStyleValue(rawValue: .blue), + 10: MGLStyleValue(rawValue: .white), + ] + + layer.circleColor = MGLStyleValue(interpolationMode: .interval, + sourceStops: stops, + attributeName: "mag", + options: [.defaultValue: MGLStyleValue<UIColor>(rawValue: .green)]) + #endif + //#-end-example-code + } + + func testUsingStyleFunctionsAtRuntime$Categorical() { + let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil) + let layer = MGLCircleStyleLayer(identifier: "circles", source: source) + + //#-example-code + #if os(macOS) + let categoricalStops = [ + "earthquake": MGLStyleValue<NSColor>(rawValue: .orange), + "explosion": MGLStyleValue(rawValue: .red), + "quarry blast": MGLStyleValue(rawValue: .yellow), + ] + + layer.circleColor = MGLStyleValue(interpolationMode: .categorical, + sourceStops: categoricalStops, + attributeName: "type", + options: [.defaultValue: MGLStyleValue<NSColor>(rawValue: .blue)]) + #else + let categoricalStops = [ + "earthquake": MGLStyleValue<UIColor>(rawValue: .orange), + "explosion": MGLStyleValue(rawValue: .red), + "quarry blast": MGLStyleValue(rawValue: .yellow), + ] + + layer.circleColor = MGLStyleValue(interpolationMode: .categorical, + sourceStops: categoricalStops, + attributeName: "type", + options: [.defaultValue: MGLStyleValue<UIColor>(rawValue: .blue)]) + #endif + //#-end-example-code + } + + func testUsingStyleFunctionsAtRuntime$Identity() { + let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil) + let layer = MGLCircleStyleLayer(identifier: "circles", source: source) + + //#-example-code + layer.circleRadius = MGLStyleValue(interpolationMode: .identity, + sourceStops: nil, + attributeName: "mag", + options: [.defaultValue: MGLStyleValue<NSNumber>(rawValue: 0)]) + //#-end-example-code + } +} diff --git a/platform/darwin/test/MGLFillExtrusionStyleLayerTests.mm b/platform/darwin/test/MGLFillExtrusionStyleLayerTests.mm new file mode 100644 index 0000000000..5d99c815ea --- /dev/null +++ b/platform/darwin/test/MGLFillExtrusionStyleLayerTests.mm @@ -0,0 +1,445 @@ +// This file is generated. +// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. + +#import "MGLStyleLayerTests.h" +#import "../../darwin/src/NSDate+MGLAdditions.h" + +#import "MGLStyleLayer_Private.h" + +#include <mbgl/style/layers/fill_extrusion_layer.hpp> +#include <mbgl/style/transition_options.hpp> + +@interface MGLFillExtrusionLayerTests : MGLStyleLayerTests +@end + +@implementation MGLFillExtrusionLayerTests + ++ (NSString *)layerType { + return @"fill-extrusion"; +} + +- (void)testPredicates { + MGLPointFeature *feature = [[MGLPointFeature alloc] init]; + MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"sourceID" shape:feature options:nil]; + MGLFillExtrusionStyleLayer *layer = [[MGLFillExtrusionStyleLayer alloc] initWithIdentifier:@"layerID" source:source]; + + XCTAssertNil(layer.sourceLayerIdentifier); + layer.sourceLayerIdentifier = @"layerID"; + XCTAssertEqualObjects(layer.sourceLayerIdentifier, @"layerID"); + layer.sourceLayerIdentifier = nil; + XCTAssertNil(layer.sourceLayerIdentifier); + + XCTAssertNil(layer.predicate); + layer.predicate = [NSPredicate predicateWithValue:NO]; + XCTAssertEqualObjects(layer.predicate, [NSPredicate predicateWithValue:NO]); + layer.predicate = nil; + XCTAssertNil(layer.predicate); +} + +- (void)testProperties { + MGLPointFeature *feature = [[MGLPointFeature alloc] init]; + MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"sourceID" shape:feature options:nil]; + + MGLFillExtrusionStyleLayer *layer = [[MGLFillExtrusionStyleLayer alloc] initWithIdentifier:@"layerID" source:source]; + XCTAssertNotEqual(layer.rawLayer, nullptr); + XCTAssertTrue(layer.rawLayer->is<mbgl::style::FillExtrusionLayer>()); + auto rawLayer = layer.rawLayer->as<mbgl::style::FillExtrusionLayer>(); + + MGLTransition transitionTest = MGLTransitionMake(5, 4); + + + // fill-extrusion-base + { + XCTAssertTrue(rawLayer->getFillExtrusionBase().isUndefined(), + @"fill-extrusion-base should be unset initially."); + MGLStyleValue<NSNumber *> *defaultStyleValue = layer.fillExtrusionBase; + + MGLStyleValue<NSNumber *> *constantStyleValue = [MGLStyleValue<NSNumber *> valueWithRawValue:@0xff]; + layer.fillExtrusionBase = constantStyleValue; + mbgl::style::DataDrivenPropertyValue<float> propertyValue = { 0xff }; + XCTAssertEqual(rawLayer->getFillExtrusionBase(), propertyValue, + @"Setting fillExtrusionBase to a constant value should update fill-extrusion-base."); + XCTAssertEqualObjects(layer.fillExtrusionBase, constantStyleValue, + @"fillExtrusionBase should round-trip constant values."); + + MGLStyleValue<NSNumber *> * functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.fillExtrusionBase = functionStyleValue; + + mbgl::style::IntervalStops<float> intervalStops = { {{18, 0xff}} }; + propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; + + XCTAssertEqual(rawLayer->getFillExtrusionBase(), propertyValue, + @"Setting fillExtrusionBase to a camera function should update fill-extrusion-base."); + XCTAssertEqualObjects(layer.fillExtrusionBase, functionStyleValue, + @"fillExtrusionBase should round-trip camera functions."); + + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeExponential sourceStops:@{@18: constantStyleValue} attributeName:@"keyName" options:nil]; + layer.fillExtrusionBase = functionStyleValue; + + mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; + propertyValue = mbgl::style::SourceFunction<float> { "keyName", exponentialStops }; + + XCTAssertEqual(rawLayer->getFillExtrusionBase(), propertyValue, + @"Setting fillExtrusionBase to a source function should update fill-extrusion-base."); + XCTAssertEqualObjects(layer.fillExtrusionBase, functionStyleValue, + @"fillExtrusionBase should round-trip source functions."); + + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeExponential compositeStops:@{@10: @{@18: constantStyleValue}} attributeName:@"keyName" options:nil]; + layer.fillExtrusionBase = functionStyleValue; + + std::map<float, float> innerStops { {18, 0xff} }; + mbgl::style::CompositeExponentialStops<float> compositeStops { { {10.0, innerStops} }, 1.0 }; + + propertyValue = mbgl::style::CompositeFunction<float> { "keyName", compositeStops }; + + XCTAssertEqual(rawLayer->getFillExtrusionBase(), propertyValue, + @"Setting fillExtrusionBase to a composite function should update fill-extrusion-base."); + XCTAssertEqualObjects(layer.fillExtrusionBase, functionStyleValue, + @"fillExtrusionBase should round-trip composite functions."); + + + layer.fillExtrusionBase = nil; + XCTAssertTrue(rawLayer->getFillExtrusionBase().isUndefined(), + @"Unsetting fillExtrusionBase should return fill-extrusion-base to the default value."); + XCTAssertEqualObjects(layer.fillExtrusionBase, defaultStyleValue, + @"fillExtrusionBase should return the default value after being unset."); + // Transition property test + layer.fillExtrusionBaseTransition = transitionTest; + auto toptions = rawLayer->getFillExtrusionBaseTransition(); + XCTAssert(toptions.delay && MGLTimeIntervalFromDuration(*toptions.delay) == transitionTest.delay); + XCTAssert(toptions.duration && MGLTimeIntervalFromDuration(*toptions.duration) == transitionTest.duration); + + MGLTransition fillExtrusionBaseTransition = layer.fillExtrusionBaseTransition; + XCTAssertEqual(fillExtrusionBaseTransition.delay, transitionTest.delay); + XCTAssertEqual(fillExtrusionBaseTransition.duration, transitionTest.duration); + } + + // fill-extrusion-color + { + XCTAssertTrue(rawLayer->getFillExtrusionColor().isUndefined(), + @"fill-extrusion-color should be unset initially."); + MGLStyleValue<MGLColor *> *defaultStyleValue = layer.fillExtrusionColor; + + MGLStyleValue<MGLColor *> *constantStyleValue = [MGLStyleValue<MGLColor *> valueWithRawValue:[MGLColor redColor]]; + layer.fillExtrusionColor = constantStyleValue; + mbgl::style::DataDrivenPropertyValue<mbgl::Color> propertyValue = { { 1, 0, 0, 1 } }; + XCTAssertEqual(rawLayer->getFillExtrusionColor(), propertyValue, + @"Setting fillExtrusionColor to a constant value should update fill-extrusion-color."); + XCTAssertEqualObjects(layer.fillExtrusionColor, constantStyleValue, + @"fillExtrusionColor should round-trip constant values."); + + MGLStyleValue<MGLColor *> * functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.fillExtrusionColor = functionStyleValue; + + mbgl::style::IntervalStops<mbgl::Color> intervalStops = { {{18, { 1, 0, 0, 1 }}} }; + propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; + + XCTAssertEqual(rawLayer->getFillExtrusionColor(), propertyValue, + @"Setting fillExtrusionColor to a camera function should update fill-extrusion-color."); + XCTAssertEqualObjects(layer.fillExtrusionColor, functionStyleValue, + @"fillExtrusionColor should round-trip camera functions."); + + functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeExponential sourceStops:@{@18: constantStyleValue} attributeName:@"keyName" options:nil]; + layer.fillExtrusionColor = functionStyleValue; + + mbgl::style::ExponentialStops<mbgl::Color> exponentialStops = { {{18, { 1, 0, 0, 1 }}}, 1.0 }; + propertyValue = mbgl::style::SourceFunction<mbgl::Color> { "keyName", exponentialStops }; + + XCTAssertEqual(rawLayer->getFillExtrusionColor(), propertyValue, + @"Setting fillExtrusionColor to a source function should update fill-extrusion-color."); + XCTAssertEqualObjects(layer.fillExtrusionColor, functionStyleValue, + @"fillExtrusionColor should round-trip source functions."); + + functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeExponential compositeStops:@{@10: @{@18: constantStyleValue}} attributeName:@"keyName" options:nil]; + layer.fillExtrusionColor = functionStyleValue; + + std::map<float, mbgl::Color> innerStops { {18, { 1, 0, 0, 1 }} }; + mbgl::style::CompositeExponentialStops<mbgl::Color> compositeStops { { {10.0, innerStops} }, 1.0 }; + + propertyValue = mbgl::style::CompositeFunction<mbgl::Color> { "keyName", compositeStops }; + + XCTAssertEqual(rawLayer->getFillExtrusionColor(), propertyValue, + @"Setting fillExtrusionColor to a composite function should update fill-extrusion-color."); + XCTAssertEqualObjects(layer.fillExtrusionColor, functionStyleValue, + @"fillExtrusionColor should round-trip composite functions."); + + + layer.fillExtrusionColor = nil; + XCTAssertTrue(rawLayer->getFillExtrusionColor().isUndefined(), + @"Unsetting fillExtrusionColor should return fill-extrusion-color to the default value."); + XCTAssertEqualObjects(layer.fillExtrusionColor, defaultStyleValue, + @"fillExtrusionColor should return the default value after being unset."); + // Transition property test + layer.fillExtrusionColorTransition = transitionTest; + auto toptions = rawLayer->getFillExtrusionColorTransition(); + XCTAssert(toptions.delay && MGLTimeIntervalFromDuration(*toptions.delay) == transitionTest.delay); + XCTAssert(toptions.duration && MGLTimeIntervalFromDuration(*toptions.duration) == transitionTest.duration); + + MGLTransition fillExtrusionColorTransition = layer.fillExtrusionColorTransition; + XCTAssertEqual(fillExtrusionColorTransition.delay, transitionTest.delay); + XCTAssertEqual(fillExtrusionColorTransition.duration, transitionTest.duration); + } + + // fill-extrusion-height + { + XCTAssertTrue(rawLayer->getFillExtrusionHeight().isUndefined(), + @"fill-extrusion-height should be unset initially."); + MGLStyleValue<NSNumber *> *defaultStyleValue = layer.fillExtrusionHeight; + + MGLStyleValue<NSNumber *> *constantStyleValue = [MGLStyleValue<NSNumber *> valueWithRawValue:@0xff]; + layer.fillExtrusionHeight = constantStyleValue; + mbgl::style::DataDrivenPropertyValue<float> propertyValue = { 0xff }; + XCTAssertEqual(rawLayer->getFillExtrusionHeight(), propertyValue, + @"Setting fillExtrusionHeight to a constant value should update fill-extrusion-height."); + XCTAssertEqualObjects(layer.fillExtrusionHeight, constantStyleValue, + @"fillExtrusionHeight should round-trip constant values."); + + MGLStyleValue<NSNumber *> * functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.fillExtrusionHeight = functionStyleValue; + + mbgl::style::IntervalStops<float> intervalStops = { {{18, 0xff}} }; + propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; + + XCTAssertEqual(rawLayer->getFillExtrusionHeight(), propertyValue, + @"Setting fillExtrusionHeight to a camera function should update fill-extrusion-height."); + XCTAssertEqualObjects(layer.fillExtrusionHeight, functionStyleValue, + @"fillExtrusionHeight should round-trip camera functions."); + + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeExponential sourceStops:@{@18: constantStyleValue} attributeName:@"keyName" options:nil]; + layer.fillExtrusionHeight = functionStyleValue; + + mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; + propertyValue = mbgl::style::SourceFunction<float> { "keyName", exponentialStops }; + + XCTAssertEqual(rawLayer->getFillExtrusionHeight(), propertyValue, + @"Setting fillExtrusionHeight to a source function should update fill-extrusion-height."); + XCTAssertEqualObjects(layer.fillExtrusionHeight, functionStyleValue, + @"fillExtrusionHeight should round-trip source functions."); + + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeExponential compositeStops:@{@10: @{@18: constantStyleValue}} attributeName:@"keyName" options:nil]; + layer.fillExtrusionHeight = functionStyleValue; + + std::map<float, float> innerStops { {18, 0xff} }; + mbgl::style::CompositeExponentialStops<float> compositeStops { { {10.0, innerStops} }, 1.0 }; + + propertyValue = mbgl::style::CompositeFunction<float> { "keyName", compositeStops }; + + XCTAssertEqual(rawLayer->getFillExtrusionHeight(), propertyValue, + @"Setting fillExtrusionHeight to a composite function should update fill-extrusion-height."); + XCTAssertEqualObjects(layer.fillExtrusionHeight, functionStyleValue, + @"fillExtrusionHeight should round-trip composite functions."); + + + layer.fillExtrusionHeight = nil; + XCTAssertTrue(rawLayer->getFillExtrusionHeight().isUndefined(), + @"Unsetting fillExtrusionHeight should return fill-extrusion-height to the default value."); + XCTAssertEqualObjects(layer.fillExtrusionHeight, defaultStyleValue, + @"fillExtrusionHeight should return the default value after being unset."); + // Transition property test + layer.fillExtrusionHeightTransition = transitionTest; + auto toptions = rawLayer->getFillExtrusionHeightTransition(); + XCTAssert(toptions.delay && MGLTimeIntervalFromDuration(*toptions.delay) == transitionTest.delay); + XCTAssert(toptions.duration && MGLTimeIntervalFromDuration(*toptions.duration) == transitionTest.duration); + + MGLTransition fillExtrusionHeightTransition = layer.fillExtrusionHeightTransition; + XCTAssertEqual(fillExtrusionHeightTransition.delay, transitionTest.delay); + XCTAssertEqual(fillExtrusionHeightTransition.duration, transitionTest.duration); + } + + // fill-extrusion-opacity + { + XCTAssertTrue(rawLayer->getFillExtrusionOpacity().isUndefined(), + @"fill-extrusion-opacity should be unset initially."); + MGLStyleValue<NSNumber *> *defaultStyleValue = layer.fillExtrusionOpacity; + + MGLStyleValue<NSNumber *> *constantStyleValue = [MGLStyleValue<NSNumber *> valueWithRawValue:@0xff]; + layer.fillExtrusionOpacity = constantStyleValue; + mbgl::style::PropertyValue<float> propertyValue = { 0xff }; + XCTAssertEqual(rawLayer->getFillExtrusionOpacity(), propertyValue, + @"Setting fillExtrusionOpacity to a constant value should update fill-extrusion-opacity."); + XCTAssertEqualObjects(layer.fillExtrusionOpacity, constantStyleValue, + @"fillExtrusionOpacity should round-trip constant values."); + + MGLStyleValue<NSNumber *> * functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.fillExtrusionOpacity = functionStyleValue; + + mbgl::style::IntervalStops<float> intervalStops = { {{18, 0xff}} }; + propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; + + XCTAssertEqual(rawLayer->getFillExtrusionOpacity(), propertyValue, + @"Setting fillExtrusionOpacity to a camera function should update fill-extrusion-opacity."); + XCTAssertEqualObjects(layer.fillExtrusionOpacity, functionStyleValue, + @"fillExtrusionOpacity should round-trip camera functions."); + + + + layer.fillExtrusionOpacity = nil; + XCTAssertTrue(rawLayer->getFillExtrusionOpacity().isUndefined(), + @"Unsetting fillExtrusionOpacity should return fill-extrusion-opacity to the default value."); + XCTAssertEqualObjects(layer.fillExtrusionOpacity, defaultStyleValue, + @"fillExtrusionOpacity should return the default value after being unset."); + + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.fillExtrusionOpacity = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.fillExtrusionOpacity = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + // Transition property test + layer.fillExtrusionOpacityTransition = transitionTest; + auto toptions = rawLayer->getFillExtrusionOpacityTransition(); + XCTAssert(toptions.delay && MGLTimeIntervalFromDuration(*toptions.delay) == transitionTest.delay); + XCTAssert(toptions.duration && MGLTimeIntervalFromDuration(*toptions.duration) == transitionTest.duration); + + MGLTransition fillExtrusionOpacityTransition = layer.fillExtrusionOpacityTransition; + XCTAssertEqual(fillExtrusionOpacityTransition.delay, transitionTest.delay); + XCTAssertEqual(fillExtrusionOpacityTransition.duration, transitionTest.duration); + } + + // fill-extrusion-pattern + { + XCTAssertTrue(rawLayer->getFillExtrusionPattern().isUndefined(), + @"fill-extrusion-pattern should be unset initially."); + MGLStyleValue<NSString *> *defaultStyleValue = layer.fillExtrusionPattern; + + MGLStyleValue<NSString *> *constantStyleValue = [MGLStyleValue<NSString *> valueWithRawValue:@"Fill Extrusion Pattern"]; + layer.fillExtrusionPattern = constantStyleValue; + mbgl::style::PropertyValue<std::string> propertyValue = { "Fill Extrusion Pattern" }; + XCTAssertEqual(rawLayer->getFillExtrusionPattern(), propertyValue, + @"Setting fillExtrusionPattern to a constant value should update fill-extrusion-pattern."); + XCTAssertEqualObjects(layer.fillExtrusionPattern, constantStyleValue, + @"fillExtrusionPattern should round-trip constant values."); + + MGLStyleValue<NSString *> * functionStyleValue = [MGLStyleValue<NSString *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.fillExtrusionPattern = functionStyleValue; + + mbgl::style::IntervalStops<std::string> intervalStops = { {{18, "Fill Extrusion Pattern"}} }; + propertyValue = mbgl::style::CameraFunction<std::string> { intervalStops }; + + XCTAssertEqual(rawLayer->getFillExtrusionPattern(), propertyValue, + @"Setting fillExtrusionPattern to a camera function should update fill-extrusion-pattern."); + XCTAssertEqualObjects(layer.fillExtrusionPattern, functionStyleValue, + @"fillExtrusionPattern should round-trip camera functions."); + + + + layer.fillExtrusionPattern = nil; + XCTAssertTrue(rawLayer->getFillExtrusionPattern().isUndefined(), + @"Unsetting fillExtrusionPattern should return fill-extrusion-pattern to the default value."); + XCTAssertEqualObjects(layer.fillExtrusionPattern, defaultStyleValue, + @"fillExtrusionPattern should return the default value after being unset."); + + functionStyleValue = [MGLStyleValue<NSString *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.fillExtrusionPattern = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + functionStyleValue = [MGLStyleValue<NSString *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.fillExtrusionPattern = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + // Transition property test + layer.fillExtrusionPatternTransition = transitionTest; + auto toptions = rawLayer->getFillExtrusionPatternTransition(); + XCTAssert(toptions.delay && MGLTimeIntervalFromDuration(*toptions.delay) == transitionTest.delay); + XCTAssert(toptions.duration && MGLTimeIntervalFromDuration(*toptions.duration) == transitionTest.duration); + + MGLTransition fillExtrusionPatternTransition = layer.fillExtrusionPatternTransition; + XCTAssertEqual(fillExtrusionPatternTransition.delay, transitionTest.delay); + XCTAssertEqual(fillExtrusionPatternTransition.duration, transitionTest.duration); + } + + // fill-extrusion-translate + { + XCTAssertTrue(rawLayer->getFillExtrusionTranslate().isUndefined(), + @"fill-extrusion-translate should be unset initially."); + MGLStyleValue<NSValue *> *defaultStyleValue = layer.fillExtrusionTranslation; + + MGLStyleValue<NSValue *> *constantStyleValue = [MGLStyleValue<NSValue *> valueWithRawValue: +#if TARGET_OS_IPHONE + [NSValue valueWithCGVector:CGVectorMake(1, 1)] +#else + [NSValue valueWithMGLVector:CGVectorMake(1, -1)] +#endif + ]; + layer.fillExtrusionTranslation = constantStyleValue; + mbgl::style::PropertyValue<std::array<float, 2>> propertyValue = { { 1, 1 } }; + XCTAssertEqual(rawLayer->getFillExtrusionTranslate(), propertyValue, + @"Setting fillExtrusionTranslation to a constant value should update fill-extrusion-translate."); + XCTAssertEqualObjects(layer.fillExtrusionTranslation, constantStyleValue, + @"fillExtrusionTranslation should round-trip constant values."); + + MGLStyleValue<NSValue *> * functionStyleValue = [MGLStyleValue<NSValue *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.fillExtrusionTranslation = functionStyleValue; + + mbgl::style::IntervalStops<std::array<float, 2>> intervalStops = { {{18, { 1, 1 }}} }; + propertyValue = mbgl::style::CameraFunction<std::array<float, 2>> { intervalStops }; + + XCTAssertEqual(rawLayer->getFillExtrusionTranslate(), propertyValue, + @"Setting fillExtrusionTranslation to a camera function should update fill-extrusion-translate."); + XCTAssertEqualObjects(layer.fillExtrusionTranslation, functionStyleValue, + @"fillExtrusionTranslation should round-trip camera functions."); + + + + layer.fillExtrusionTranslation = nil; + XCTAssertTrue(rawLayer->getFillExtrusionTranslate().isUndefined(), + @"Unsetting fillExtrusionTranslation should return fill-extrusion-translate to the default value."); + XCTAssertEqualObjects(layer.fillExtrusionTranslation, defaultStyleValue, + @"fillExtrusionTranslation should return the default value after being unset."); + + functionStyleValue = [MGLStyleValue<NSValue *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.fillExtrusionTranslation = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + functionStyleValue = [MGLStyleValue<NSValue *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.fillExtrusionTranslation = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + } + + // fill-extrusion-translate-anchor + { + XCTAssertTrue(rawLayer->getFillExtrusionTranslateAnchor().isUndefined(), + @"fill-extrusion-translate-anchor should be unset initially."); + MGLStyleValue<NSValue *> *defaultStyleValue = layer.fillExtrusionTranslationAnchor; + + MGLStyleValue<NSValue *> *constantStyleValue = [MGLStyleValue<NSValue *> valueWithRawValue:[NSValue valueWithMGLFillExtrusionTranslationAnchor:MGLFillExtrusionTranslationAnchorViewport]]; + layer.fillExtrusionTranslationAnchor = constantStyleValue; + mbgl::style::PropertyValue<mbgl::style::TranslateAnchorType> propertyValue = { mbgl::style::TranslateAnchorType::Viewport }; + XCTAssertEqual(rawLayer->getFillExtrusionTranslateAnchor(), propertyValue, + @"Setting fillExtrusionTranslationAnchor to a constant value should update fill-extrusion-translate-anchor."); + XCTAssertEqualObjects(layer.fillExtrusionTranslationAnchor, constantStyleValue, + @"fillExtrusionTranslationAnchor should round-trip constant values."); + + MGLStyleValue<NSValue *> * functionStyleValue = [MGLStyleValue<NSValue *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.fillExtrusionTranslationAnchor = functionStyleValue; + + mbgl::style::IntervalStops<mbgl::style::TranslateAnchorType> intervalStops = { {{18, mbgl::style::TranslateAnchorType::Viewport}} }; + propertyValue = mbgl::style::CameraFunction<mbgl::style::TranslateAnchorType> { intervalStops }; + + XCTAssertEqual(rawLayer->getFillExtrusionTranslateAnchor(), propertyValue, + @"Setting fillExtrusionTranslationAnchor to a camera function should update fill-extrusion-translate-anchor."); + XCTAssertEqualObjects(layer.fillExtrusionTranslationAnchor, functionStyleValue, + @"fillExtrusionTranslationAnchor should round-trip camera functions."); + + + + layer.fillExtrusionTranslationAnchor = nil; + XCTAssertTrue(rawLayer->getFillExtrusionTranslateAnchor().isUndefined(), + @"Unsetting fillExtrusionTranslationAnchor should return fill-extrusion-translate-anchor to the default value."); + XCTAssertEqualObjects(layer.fillExtrusionTranslationAnchor, defaultStyleValue, + @"fillExtrusionTranslationAnchor should return the default value after being unset."); + + functionStyleValue = [MGLStyleValue<NSValue *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.fillExtrusionTranslationAnchor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + functionStyleValue = [MGLStyleValue<NSValue *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.fillExtrusionTranslationAnchor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + } +} + +- (void)testPropertyNames { + [self testPropertyName:@"fill-extrusion-base" isBoolean:NO]; + [self testPropertyName:@"fill-extrusion-color" isBoolean:NO]; + [self testPropertyName:@"fill-extrusion-height" isBoolean:NO]; + [self testPropertyName:@"fill-extrusion-opacity" isBoolean:NO]; + [self testPropertyName:@"fill-extrusion-pattern" isBoolean:NO]; + [self testPropertyName:@"fill-extrusion-translation" isBoolean:NO]; + [self testPropertyName:@"fill-extrusion-translation-anchor" isBoolean:NO]; +} + +- (void)testValueAdditions { + XCTAssertEqual([NSValue valueWithMGLFillExtrusionTranslationAnchor:MGLFillExtrusionTranslationAnchorMap].MGLFillExtrusionTranslationAnchorValue, MGLFillExtrusionTranslationAnchorMap); + XCTAssertEqual([NSValue valueWithMGLFillExtrusionTranslationAnchor:MGLFillExtrusionTranslationAnchorViewport].MGLFillExtrusionTranslationAnchorValue, MGLFillExtrusionTranslationAnchorViewport); +} + +@end diff --git a/platform/darwin/test/MGLSDKTestHelpers.swift b/platform/darwin/test/MGLSDKTestHelpers.swift new file mode 100644 index 0000000000..82b5caa273 --- /dev/null +++ b/platform/darwin/test/MGLSDKTestHelpers.swift @@ -0,0 +1,47 @@ +import Foundation + +class MGLSDKTestHelpers { + + class func checkTestsContainAllMethods(testClass: Swift.AnyClass, in p: Protocol) { + let testMethods = self.classMethodDescriptions(testClass) + let subjectMethods = self.protocolMethodDescriptions(p) + + for method in subjectMethods { + if !testMethods.contains(method) { + XCTFail("\(String(describing: testClass)) does not contain \(method) from \(String(describing: p))") + } + } + + XCTAssert(true) + } + +} + +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) + for i in 0..<Int(methodCount) { + let description: objc_method_description = methodDescriptionList[i] + methods.insert(description.name.description) + } + free(methodDescriptionList) + return methods + } + + class func classMethodDescriptions(_ cls: Swift.AnyClass) -> Set<String> { + var methods = Set<String>() + var methodCount = UInt32() + let methodList: UnsafeMutablePointer<Method?>! = class_copyMethodList(cls, &methodCount) + for i in 0..<Int(methodCount) { + let method = methodList[i] + let selector : Selector = method_getName(method) + methods.insert(selector.description) + } + free(methodList) + return methods + } + +} diff --git a/platform/darwin/test/MGLShapeSourceTests.mm b/platform/darwin/test/MGLShapeSourceTests.mm index ba85d76020..561af7f3d0 100644 --- a/platform/darwin/test/MGLShapeSourceTests.mm +++ b/platform/darwin/test/MGLShapeSourceTests.mm @@ -104,11 +104,11 @@ - (void)testMGLShapeSourceWithPolygonFeatures { CLLocationCoordinate2D coordinates[] = { - CLLocationCoordinate2DMake(100.0, 0.0), - CLLocationCoordinate2DMake(101.0, 0.0), - CLLocationCoordinate2DMake(101.0, 1.0), - CLLocationCoordinate2DMake(100.0, 1.0), - CLLocationCoordinate2DMake(100.0, 0.0)}; + CLLocationCoordinate2DMake(0.0, 100.0), + CLLocationCoordinate2DMake(0.0, 101.0), + CLLocationCoordinate2DMake(1.0, 101.0), + CLLocationCoordinate2DMake(1.0, 100.0), + CLLocationCoordinate2DMake(0.0, 100.0)}; MGLPolygonFeature *polygonFeature = [MGLPolygonFeature polygonWithCoordinates:coordinates count:5]; polygonFeature.identifier = @"feature-id"; @@ -150,18 +150,18 @@ - (void)testMGLShapeSourceWithPolygonFeaturesInculdingInteriorPolygons { CLLocationCoordinate2D coordinates[] = { - CLLocationCoordinate2DMake(100.0, 0.0), - CLLocationCoordinate2DMake(101.0, 0.0), - CLLocationCoordinate2DMake(101.0, 1.0), - CLLocationCoordinate2DMake(100.0, 1.0), - CLLocationCoordinate2DMake(100.0, 0.0)}; + CLLocationCoordinate2DMake(0.0, 100.0), + CLLocationCoordinate2DMake(0.0, 101.0), + CLLocationCoordinate2DMake(1.0, 101.0), + CLLocationCoordinate2DMake(1.0, 100.0), + CLLocationCoordinate2DMake(0.0, 100.0)}; CLLocationCoordinate2D interiorCoordinates[] = { - CLLocationCoordinate2DMake(100.2, 0.2), - CLLocationCoordinate2DMake(100.8, 0.2), - CLLocationCoordinate2DMake(100.8, 0.8), - CLLocationCoordinate2DMake(100.2, 0.8), - CLLocationCoordinate2DMake(100.2, 0.2)}; + CLLocationCoordinate2DMake(0.2, 100.2), + CLLocationCoordinate2DMake(0.2, 100.8), + CLLocationCoordinate2DMake(0.8, 100.8), + CLLocationCoordinate2DMake(0.8, 100.2), + CLLocationCoordinate2DMake(0.2, 100.2)}; MGLPolygon *polygon = [MGLPolygon polygonWithCoordinates:interiorCoordinates count:5]; @@ -188,18 +188,18 @@ - (void)testMGLShapeSourceWithMultiPolygonFeatures { CLLocationCoordinate2D coordinates[] = { - CLLocationCoordinate2DMake(100.0, 0.0), - CLLocationCoordinate2DMake(101.0, 0.0), - CLLocationCoordinate2DMake(101.0, 1.0), - CLLocationCoordinate2DMake(100.0, 1.0), - CLLocationCoordinate2DMake(100.0, 0.0)}; + CLLocationCoordinate2DMake(0.0, 100.0), + CLLocationCoordinate2DMake(0.0, 101.0), + CLLocationCoordinate2DMake(1.0, 101.0), + CLLocationCoordinate2DMake(1.0, 100.0), + CLLocationCoordinate2DMake(0.0, 100.0)}; CLLocationCoordinate2D interiorCoordinates[] = { - CLLocationCoordinate2DMake(100.2, 0.2), - CLLocationCoordinate2DMake(100.8, 0.2), - CLLocationCoordinate2DMake(100.8, 0.8), - CLLocationCoordinate2DMake(100.2, 0.8), - CLLocationCoordinate2DMake(100.2, 0.2)}; + CLLocationCoordinate2DMake(0.2, 100.2), + CLLocationCoordinate2DMake(0.2, 100.8), + CLLocationCoordinate2DMake(0.8, 100.8), + CLLocationCoordinate2DMake(0.8, 100.2), + CLLocationCoordinate2DMake(0.2, 100.2)}; MGLPolygon *polygon = [MGLPolygon polygonWithCoordinates:interiorCoordinates count:5]; @@ -216,7 +216,7 @@ - (void)testMGLShapeSourceWithPointFeature { MGLPointFeature *pointFeature = [MGLPointFeature new]; - pointFeature.coordinate = CLLocationCoordinate2DMake(100.2, 0.2); + pointFeature.coordinate = CLLocationCoordinate2DMake(0.2, 100.2); MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"souce-id" shape:pointFeature options:nil]; @@ -226,11 +226,11 @@ - (void)testMGLShapeSourceWithPointCollectionFeature { CLLocationCoordinate2D coordinates[] = { - CLLocationCoordinate2DMake(100.0, 0.0), - CLLocationCoordinate2DMake(101.0, 0.0), - CLLocationCoordinate2DMake(101.0, 1.0), - CLLocationCoordinate2DMake(100.0, 1.0), - CLLocationCoordinate2DMake(100.0, 0.0)}; + CLLocationCoordinate2DMake(0.0, 100.0), + CLLocationCoordinate2DMake(0.0, 101.0), + CLLocationCoordinate2DMake(1.0, 101.0), + CLLocationCoordinate2DMake(1.0, 100.0), + CLLocationCoordinate2DMake(0.0, 100.0)}; MGLPointCollectionFeature *pointCollectionFeature = [MGLPointCollectionFeature pointCollectionWithCoordinates:coordinates count:5]; MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"souce-id" shape:pointCollectionFeature options:nil]; @@ -240,18 +240,18 @@ - (void)testMGLShapeSourceWithShapeCollectionFeatures { CLLocationCoordinate2D coordinates[] = { - CLLocationCoordinate2DMake(100.0, 0.0), - CLLocationCoordinate2DMake(101.0, 0.0), - CLLocationCoordinate2DMake(101.0, 1.0), - CLLocationCoordinate2DMake(100.0, 1.0), - CLLocationCoordinate2DMake(100.0, 0.0)}; + CLLocationCoordinate2DMake(0.0, 100.0), + CLLocationCoordinate2DMake(0.0, 101.0), + CLLocationCoordinate2DMake(1.0, 101.0), + CLLocationCoordinate2DMake(1.0, 100.0), + CLLocationCoordinate2DMake(0.0, 100.0)}; CLLocationCoordinate2D interiorCoordinates[] = { - CLLocationCoordinate2DMake(100.2, 0.2), - CLLocationCoordinate2DMake(100.8, 0.2), - CLLocationCoordinate2DMake(100.8, 0.8), - CLLocationCoordinate2DMake(100.2, 0.8), - CLLocationCoordinate2DMake(100.2, 0.2)}; + CLLocationCoordinate2DMake(0.2, 100.2), + CLLocationCoordinate2DMake(0.2, 100.8), + CLLocationCoordinate2DMake(0.8, 100.8), + CLLocationCoordinate2DMake(0.8, 100.2), + CLLocationCoordinate2DMake(0.2, 100.2)}; MGLPolygon *polygon = [MGLPolygon polygonWithCoordinates:interiorCoordinates count:5]; @@ -267,7 +267,7 @@ MGLPointCollectionFeature *pointCollectionFeature = [MGLPointCollectionFeature pointCollectionWithCoordinates:coordinates count:5]; MGLPointFeature *pointFeature = [MGLPointFeature new]; - pointFeature.coordinate = CLLocationCoordinate2DMake(100.2, 0.2); + pointFeature.coordinate = CLLocationCoordinate2DMake(0.2, 100.2); MGLShapeCollectionFeature *shapeCollectionFeature = [MGLShapeCollectionFeature shapeCollectionWithShapes:@[polygonFeature, polylineFeature, multiPolygonFeature, multiPolylineFeature, pointCollectionFeature, pointFeature]]; @@ -280,11 +280,11 @@ - (void)testMGLShapeSourceWithFeaturesConvenienceInitializer { CLLocationCoordinate2D coordinates[] = { - CLLocationCoordinate2DMake(100.0, 0.0), - CLLocationCoordinate2DMake(101.0, 0.0), - CLLocationCoordinate2DMake(101.0, 1.0), - CLLocationCoordinate2DMake(100.0, 1.0), - CLLocationCoordinate2DMake(100.0, 0.0)}; + CLLocationCoordinate2DMake(0.0, 100.0), + CLLocationCoordinate2DMake(0.0, 101.0), + CLLocationCoordinate2DMake(1.0, 101.0), + CLLocationCoordinate2DMake(1.0, 100.0), + CLLocationCoordinate2DMake(0.0, 100.0)}; MGLPolygonFeature *polygonFeature = [MGLPolygonFeature polygonWithCoordinates:coordinates count:sizeof(coordinates)/sizeof(coordinates[0]) interiorPolygons:nil]; @@ -302,11 +302,11 @@ - (void)testMGLShapeSourceWithShapesConvenienceInitializer { CLLocationCoordinate2D coordinates[] = { - CLLocationCoordinate2DMake(100.0, 0.0), - CLLocationCoordinate2DMake(101.0, 0.0), - CLLocationCoordinate2DMake(101.0, 1.0), - CLLocationCoordinate2DMake(100.0, 1.0), - CLLocationCoordinate2DMake(100.0, 0.0)}; + CLLocationCoordinate2DMake(0.0, 100.0), + CLLocationCoordinate2DMake(0.0, 101.0), + CLLocationCoordinate2DMake(1.0, 101.0), + CLLocationCoordinate2DMake(1.0, 100.0), + CLLocationCoordinate2DMake(0.0, 100.0)}; MGLPolygon *polygon = [MGLPolygon polygonWithCoordinates:coordinates count:sizeof(coordinates)/sizeof(coordinates[0]) interiorPolygons:nil]; diff --git a/platform/darwin/test/MGLSourceQueryTests.m b/platform/darwin/test/MGLSourceQueryTests.m index 28e968146b..d1ef180a52 100644 --- a/platform/darwin/test/MGLSourceQueryTests.m +++ b/platform/darwin/test/MGLSourceQueryTests.m @@ -1,73 +1,25 @@ #import <Mapbox/Mapbox.h> - -#import "NSBundle+MGLAdditions.h" - #import <XCTest/XCTest.h> -#if TARGET_OS_IPHONE - #import <UIKit/UIKit.h> -#else - #import <Cocoa/Cocoa.h> -#endif @interface MGLSourceQueryTests : XCTestCase <MGLMapViewDelegate> -@property (nonatomic) MGLMapView *mapView; -@property (nonatomic) MGLStyle *style; - @end -@implementation MGLSourceQueryTests { - XCTestExpectation *_styleLoadingExpectation; -} - -- (void)setUp { - [super setUp]; - - [MGLAccountManager setAccessToken:@"pk.feedcafedeadbeefbadebede"]; - NSURL *styleURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"query-style" withExtension:@"json"]; - self.mapView = [[MGLMapView alloc] initWithFrame:CGRectMake(0, 0, 100, 100) styleURL:styleURL]; - self.mapView.delegate = self; - if (!self.mapView.style) { - _styleLoadingExpectation = [self expectationWithDescription:@"Map view should finish loading style."]; - [self waitForExpectationsWithTimeout:1 handler:nil]; - } -} - -- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style { - XCTAssertNotNil(mapView.style); - XCTAssertEqual(mapView.style, style); - - [_styleLoadingExpectation fulfill]; -} - -- (void)tearDown { - _styleLoadingExpectation = nil; - self.mapView = nil; - - [super tearDown]; -} - -- (MGLStyle *)style { - return self.mapView.style; -} +@implementation MGLSourceQueryTests - (void) testQueryVectorSource { - MGLVectorSource *source = (MGLVectorSource *)[self.style sourceWithIdentifier:@"source5"]; - + MGLVectorSource *source = [[MGLVectorSource alloc] initWithIdentifier:@"vector" tileURLTemplates:@[@"fake"] options:nil]; NSSet *sourceLayers = [NSSet setWithObjects:@"buildings", @"water", nil]; NSArray* features = [source featuresInSourceLayersWithIdentifiers:sourceLayers predicate:nil]; - // Source won't be loaded yet, so features is 0 + // Source not added yet, so features is 0 XCTAssertEqual([features count], 0); } - (void) testQueryShapeSource { - MGLShapeSource *source = (MGLShapeSource *)[self.style sourceWithIdentifier:@"source4"]; - - NSPredicate *eqPredicate = [NSPredicate predicateWithFormat:@"key1 == 'value1'"]; - NSArray* features = [source featuresMatchingPredicate:eqPredicate]; - // Source won't be loaded yet, so features is 0 + MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"shape" shape:[MGLShapeCollection shapeCollectionWithShapes:@[]] options:nil]; + NSArray* features = [source featuresMatchingPredicate:nil]; + // Source not added yet, so features is 0 XCTAssertEqual([features count], 0); - } @end diff --git a/platform/darwin/test/MGLStyleLayerTests.mm.ejs b/platform/darwin/test/MGLStyleLayerTests.mm.ejs index a405ae58c4..5fdfc3d44e 100644 --- a/platform/darwin/test/MGLStyleLayerTests.mm.ejs +++ b/platform/darwin/test/MGLStyleLayerTests.mm.ejs @@ -11,7 +11,7 @@ #import "MGLStyleLayer_Private.h" -#include <mbgl/style/layers/<%- type %>_layer.hpp> +#include <mbgl/style/layers/<%- type.replace('-', '_') %>_layer.hpp> #include <mbgl/style/transition_options.hpp> @interface MGL<%- camelize(type) %>LayerTests : MGLStyleLayerTests diff --git a/platform/darwin/test/MGLStyleTests.mm b/platform/darwin/test/MGLStyleTests.mm index 36772e556d..f80d5776f0 100644 --- a/platform/darwin/test/MGLStyleTests.mm +++ b/platform/darwin/test/MGLStyleTests.mm @@ -55,13 +55,19 @@ } - (void)testUnversionedStyleURLs { + XCTAssertEqual(mbgl::util::default_styles::streets.currentVersion, MGLStyleDefaultVersion, + "mbgl::util::default_styles::streets.currentVersion and MGLStyleDefaultVersion disagree."); + + XCTAssertEqualObjects([MGLStyle streetsStyleURL].absoluteString, @(mbgl::util::default_styles::streets.url)); + XCTAssertEqualObjects([MGLStyle outdoorsStyleURL].absoluteString, @(mbgl::util::default_styles::outdoors.url)); + XCTAssertEqualObjects([MGLStyle lightStyleURL].absoluteString, @(mbgl::util::default_styles::light.url)); + 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 streetsStyleURL].absoluteString, @"mapbox://styles/mapbox/streets-v8"); XCTAssertEqualObjects([MGLStyle emeraldStyleURL].absoluteString, @"mapbox://styles/mapbox/emerald-v8"); - XCTAssertEqualObjects([MGLStyle lightStyleURL].absoluteString, @"mapbox://styles/mapbox/light-v8"); - XCTAssertEqualObjects([MGLStyle darkStyleURL].absoluteString, @"mapbox://styles/mapbox/dark-v8"); - XCTAssertEqualObjects([MGLStyle satelliteStyleURL].absoluteString, @"mapbox://styles/mapbox/satellite-v8"); XCTAssertEqualObjects([MGLStyle hybridStyleURL].absoluteString, @"mapbox://styles/mapbox/satellite-hybrid-v8"); #pragma clang diagnostic pop } @@ -69,20 +75,40 @@ - (void)testVersionedStyleURLs { // Test that all the default styles have publicly-declared MGLStyle class // methods and that the URLs all have the right values. - XCTAssertEqualObjects([MGLStyle streetsStyleURLWithVersion:MGLStyleDefaultVersion].absoluteString, @(mbgl::util::default_styles::streets.url)); - XCTAssertEqualObjects([MGLStyle streetsStyleURLWithVersion:99].absoluteString, @"mapbox://styles/mapbox/streets-v99"); - XCTAssertEqualObjects([MGLStyle outdoorsStyleURLWithVersion:MGLStyleDefaultVersion].absoluteString, @(mbgl::util::default_styles::outdoors.url)); - XCTAssertEqualObjects([MGLStyle outdoorsStyleURLWithVersion:99].absoluteString, @"mapbox://styles/mapbox/outdoors-v99"); - XCTAssertEqualObjects([MGLStyle lightStyleURLWithVersion:MGLStyleDefaultVersion].absoluteString, @(mbgl::util::default_styles::light.url)); - XCTAssertEqualObjects([MGLStyle lightStyleURLWithVersion:99].absoluteString, @"mapbox://styles/mapbox/light-v99"); - XCTAssertEqualObjects([MGLStyle darkStyleURLWithVersion:MGLStyleDefaultVersion].absoluteString, @(mbgl::util::default_styles::dark.url)); - XCTAssertEqualObjects([MGLStyle darkStyleURLWithVersion:99].absoluteString, @"mapbox://styles/mapbox/dark-v99"); - XCTAssertEqualObjects([MGLStyle satelliteStyleURLWithVersion:MGLStyleDefaultVersion].absoluteString, @(mbgl::util::default_styles::satellite.url)); - XCTAssertEqualObjects([MGLStyle satelliteStyleURLWithVersion:99].absoluteString, @"mapbox://styles/mapbox/satellite-v99"); - XCTAssertEqualObjects([MGLStyle satelliteStreetsStyleURLWithVersion:MGLStyleDefaultVersion].absoluteString, @(mbgl::util::default_styles::satelliteStreets.url)); - XCTAssertEqualObjects([MGLStyle satelliteStreetsStyleURLWithVersion:99].absoluteString, @"mapbox://styles/mapbox/satellite-streets-v99"); - - static_assert(6 == mbgl::util::default_styles::numOrderedStyles, + XCTAssertEqualObjects([MGLStyle streetsStyleURLWithVersion:mbgl::util::default_styles::streets.currentVersion].absoluteString, + @(mbgl::util::default_styles::streets.url)); + XCTAssertEqualObjects([MGLStyle streetsStyleURLWithVersion:99].absoluteString, + @"mapbox://styles/mapbox/streets-v99"); + XCTAssertEqualObjects([MGLStyle outdoorsStyleURLWithVersion:mbgl::util::default_styles::outdoors.currentVersion].absoluteString, + @(mbgl::util::default_styles::outdoors.url)); + XCTAssertEqualObjects([MGLStyle outdoorsStyleURLWithVersion:99].absoluteString, + @"mapbox://styles/mapbox/outdoors-v99"); + XCTAssertEqualObjects([MGLStyle lightStyleURLWithVersion:mbgl::util::default_styles::light.currentVersion].absoluteString, + @(mbgl::util::default_styles::light.url)); + XCTAssertEqualObjects([MGLStyle lightStyleURLWithVersion:99].absoluteString, + @"mapbox://styles/mapbox/light-v99"); + XCTAssertEqualObjects([MGLStyle darkStyleURLWithVersion:mbgl::util::default_styles::dark.currentVersion].absoluteString, + @(mbgl::util::default_styles::dark.url)); + XCTAssertEqualObjects([MGLStyle darkStyleURLWithVersion:99].absoluteString, + @"mapbox://styles/mapbox/dark-v99"); + XCTAssertEqualObjects([MGLStyle satelliteStyleURLWithVersion:mbgl::util::default_styles::satellite.currentVersion].absoluteString, + @(mbgl::util::default_styles::satellite.url)); + XCTAssertEqualObjects([MGLStyle satelliteStyleURLWithVersion:99].absoluteString, + @"mapbox://styles/mapbox/satellite-v99"); + XCTAssertEqualObjects([MGLStyle satelliteStreetsStyleURLWithVersion:mbgl::util::default_styles::satelliteStreets.currentVersion].absoluteString, + @(mbgl::util::default_styles::satelliteStreets.url)); + XCTAssertEqualObjects([MGLStyle satelliteStreetsStyleURLWithVersion:99].absoluteString, + @"mapbox://styles/mapbox/satellite-streets-v99"); + 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"); + + static_assert(8 == mbgl::util::default_styles::numOrderedStyles, "MGLStyleTests isn’t testing all the styles in mbgl::util::default_styles."); } @@ -119,19 +145,6 @@ XCTAssertNil(versionedMethodError, @"Error compiling regular expression to search for versioned methods."); NSUInteger numVersionedMethodDeclarations = [versionedMethodExpression numberOfMatchesInString:styleHeader options:0 range:NSMakeRange(0, styleHeader.length)]; XCTAssertEqual(numVersionedMethodDeclarations, numVersionedMethods); - - // Test that “current version is” statements are present and current for all versioned style methods. - NSError *versionError; - NSString *versionExpressionString = @(R"RE(current version is `(\d+)`)RE"); - NSRegularExpression *versionExpression = [NSRegularExpression regularExpressionWithPattern:versionExpressionString options:0 error:&versionError]; - XCTAssertNil(versionError, @"Error compiling regular expression to search for current version statements."); - NSUInteger numVersionDeclarations = [versionExpression numberOfMatchesInString:styleHeader options:0 range:NSMakeRange(0, styleHeader.length)]; - XCTAssertEqual(numVersionDeclarations, numVersionedMethods); - [versionExpression enumerateMatchesInString:styleHeader options:0 range:NSMakeRange(0, styleHeader.length) usingBlock:^(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL * _Nonnull stop) { - XCTAssertEqual(result.numberOfRanges, 2, @"Regular expression should have one capture group."); - NSString *version = [styleHeader substringWithRange:[result rangeAtIndex:1]]; - XCTAssertEqual([version integerValue], MGLStyleDefaultVersion, @"Versioned style URL method should document current version as %ld, not %ld.", MGLStyleDefaultVersion, version.integerValue); - }]; } - (void)testName { @@ -148,6 +161,7 @@ MGLShapeSource *shapeSource = [[MGLShapeSource alloc] initWithIdentifier:@"shapeSource" shape:nil options:nil]; [self.style addSource:shapeSource]; XCTAssertEqual(self.style.sources.count, initialSources.count + 1); + XCTAssertEqual(shapeSource, [self.style sourceWithIdentifier:@"shapeSource"]); [self.style removeSource:shapeSource]; XCTAssertEqual(self.style.sources.count, initialSources.count); } @@ -238,6 +252,7 @@ MGLFillStyleLayer *fillLayer = [[MGLFillStyleLayer alloc] initWithIdentifier:@"fillLayer" source:shapeSource]; [self.style addLayer:fillLayer]; XCTAssertEqual(self.style.layers.count, initialLayers.count + 1); + XCTAssertEqual(fillLayer, [self.style layerWithIdentifier:@"fillLayer"]); [self.style removeLayer:fillLayer]; XCTAssertEqual(self.style.layers.count, initialLayers.count); } diff --git a/platform/darwin/test/MGLSymbolStyleLayerTests.mm b/platform/darwin/test/MGLSymbolStyleLayerTests.mm index e3e473ef78..367ebf363c 100644 --- a/platform/darwin/test/MGLSymbolStyleLayerTests.mm +++ b/platform/darwin/test/MGLSymbolStyleLayerTests.mm @@ -134,7 +134,7 @@ MGLStyleValue<NSString *> *constantStyleValue = [MGLStyleValue<NSString *> valueWithRawValue:@"Icon Image"]; layer.iconImageName = constantStyleValue; - mbgl::style::PropertyValue<std::string> propertyValue = { "Icon Image" }; + mbgl::style::DataDrivenPropertyValue<std::string> propertyValue = { "Icon Image" }; XCTAssertEqual(rawLayer->getIconImage(), propertyValue, @"Setting iconImageName to a constant value should update icon-image."); XCTAssertEqualObjects(layer.iconImageName, constantStyleValue, @@ -158,11 +158,6 @@ @"Unsetting iconImageName should return icon-image to the default value."); XCTAssertEqualObjects(layer.iconImageName, defaultStyleValue, @"iconImageName should return the default value after being unset."); - - functionStyleValue = [MGLStyleValue<NSString *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.iconImageName = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); - functionStyleValue = [MGLStyleValue<NSString *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.iconImageName = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); } // icon-offset @@ -410,7 +405,7 @@ MGLStyleValue<NSNumber *> *constantStyleValue = [MGLStyleValue<NSNumber *> valueWithRawValue:@0xff]; layer.iconScale = constantStyleValue; - mbgl::style::PropertyValue<float> propertyValue = { 0xff }; + mbgl::style::DataDrivenPropertyValue<float> propertyValue = { 0xff }; XCTAssertEqual(rawLayer->getIconSize(), propertyValue, @"Setting iconScale to a constant value should update icon-size."); XCTAssertEqualObjects(layer.iconScale, constantStyleValue, @@ -427,6 +422,29 @@ XCTAssertEqualObjects(layer.iconScale, functionStyleValue, @"iconScale should round-trip camera functions."); + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeExponential sourceStops:@{@18: constantStyleValue} attributeName:@"keyName" options:nil]; + layer.iconScale = functionStyleValue; + + mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; + propertyValue = mbgl::style::SourceFunction<float> { "keyName", exponentialStops }; + + XCTAssertEqual(rawLayer->getIconSize(), propertyValue, + @"Setting iconScale to a source function should update icon-size."); + XCTAssertEqualObjects(layer.iconScale, functionStyleValue, + @"iconScale should round-trip source functions."); + + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeExponential compositeStops:@{@10: @{@18: constantStyleValue}} attributeName:@"keyName" options:nil]; + layer.iconScale = functionStyleValue; + + std::map<float, float> innerStops { {18, 0xff} }; + mbgl::style::CompositeExponentialStops<float> compositeStops { { {10.0, innerStops} }, 1.0 }; + + propertyValue = mbgl::style::CompositeFunction<float> { "keyName", compositeStops }; + + XCTAssertEqual(rawLayer->getIconSize(), propertyValue, + @"Setting iconScale to a composite function should update icon-size."); + XCTAssertEqualObjects(layer.iconScale, functionStyleValue, + @"iconScale should round-trip composite functions."); layer.iconScale = nil; @@ -434,11 +452,6 @@ @"Unsetting iconScale should return icon-size to the default value."); XCTAssertEqualObjects(layer.iconScale, defaultStyleValue, @"iconScale should return the default value after being unset."); - - functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.iconScale = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); - functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.iconScale = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); } // icon-text-fit @@ -957,7 +970,7 @@ MGLStyleValue<NSNumber *> *constantStyleValue = [MGLStyleValue<NSNumber *> valueWithRawValue:@0xff]; layer.textFontSize = constantStyleValue; - mbgl::style::PropertyValue<float> propertyValue = { 0xff }; + mbgl::style::DataDrivenPropertyValue<float> propertyValue = { 0xff }; XCTAssertEqual(rawLayer->getTextSize(), propertyValue, @"Setting textFontSize to a constant value should update text-size."); XCTAssertEqualObjects(layer.textFontSize, constantStyleValue, @@ -974,6 +987,29 @@ XCTAssertEqualObjects(layer.textFontSize, functionStyleValue, @"textFontSize should round-trip camera functions."); + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeExponential sourceStops:@{@18: constantStyleValue} attributeName:@"keyName" options:nil]; + layer.textFontSize = functionStyleValue; + + mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; + propertyValue = mbgl::style::SourceFunction<float> { "keyName", exponentialStops }; + + XCTAssertEqual(rawLayer->getTextSize(), propertyValue, + @"Setting textFontSize to a source function should update text-size."); + XCTAssertEqualObjects(layer.textFontSize, functionStyleValue, + @"textFontSize should round-trip source functions."); + + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeExponential compositeStops:@{@10: @{@18: constantStyleValue}} attributeName:@"keyName" options:nil]; + layer.textFontSize = functionStyleValue; + + std::map<float, float> innerStops { {18, 0xff} }; + mbgl::style::CompositeExponentialStops<float> compositeStops { { {10.0, innerStops} }, 1.0 }; + + propertyValue = mbgl::style::CompositeFunction<float> { "keyName", compositeStops }; + + XCTAssertEqual(rawLayer->getTextSize(), propertyValue, + @"Setting textFontSize to a composite function should update text-size."); + XCTAssertEqualObjects(layer.textFontSize, functionStyleValue, + @"textFontSize should round-trip composite functions."); layer.textFontSize = nil; @@ -981,11 +1017,6 @@ @"Unsetting textFontSize should return text-size to the default value."); XCTAssertEqualObjects(layer.textFontSize, defaultStyleValue, @"textFontSize should return the default value after being unset."); - - functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.textFontSize = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); - functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.textFontSize = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); } // text-ignore-placement @@ -1158,7 +1189,7 @@ #endif ]; layer.textOffset = constantStyleValue; - mbgl::style::PropertyValue<std::array<float, 2>> propertyValue = { { 1, 1 } }; + mbgl::style::DataDrivenPropertyValue<std::array<float, 2>> propertyValue = { { 1, 1 } }; XCTAssertEqual(rawLayer->getTextOffset(), propertyValue, @"Setting textOffset to a constant value should update text-offset."); XCTAssertEqualObjects(layer.textOffset, constantStyleValue, @@ -1175,6 +1206,29 @@ XCTAssertEqualObjects(layer.textOffset, functionStyleValue, @"textOffset should round-trip camera functions."); + functionStyleValue = [MGLStyleValue<NSValue *> valueWithInterpolationMode:MGLInterpolationModeExponential sourceStops:@{@18: constantStyleValue} attributeName:@"keyName" options:nil]; + layer.textOffset = functionStyleValue; + + mbgl::style::ExponentialStops<std::array<float, 2>> exponentialStops = { {{18, { 1, 1 }}}, 1.0 }; + propertyValue = mbgl::style::SourceFunction<std::array<float, 2>> { "keyName", exponentialStops }; + + XCTAssertEqual(rawLayer->getTextOffset(), propertyValue, + @"Setting textOffset to a source function should update text-offset."); + XCTAssertEqualObjects(layer.textOffset, functionStyleValue, + @"textOffset should round-trip source functions."); + + functionStyleValue = [MGLStyleValue<NSValue *> valueWithInterpolationMode:MGLInterpolationModeExponential compositeStops:@{@10: @{@18: constantStyleValue}} attributeName:@"keyName" options:nil]; + layer.textOffset = functionStyleValue; + + std::map<float, std::array<float, 2>> innerStops { {18, { 1, 1 }} }; + mbgl::style::CompositeExponentialStops<std::array<float, 2>> compositeStops { { {10.0, innerStops} }, 1.0 }; + + propertyValue = mbgl::style::CompositeFunction<std::array<float, 2>> { "keyName", compositeStops }; + + XCTAssertEqual(rawLayer->getTextOffset(), propertyValue, + @"Setting textOffset to a composite function should update text-offset."); + XCTAssertEqualObjects(layer.textOffset, functionStyleValue, + @"textOffset should round-trip composite functions."); layer.textOffset = nil; @@ -1182,11 +1236,6 @@ @"Unsetting textOffset should return text-offset to the default value."); XCTAssertEqualObjects(layer.textOffset, defaultStyleValue, @"textOffset should return the default value after being unset."); - - functionStyleValue = [MGLStyleValue<NSValue *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.textOffset = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); - functionStyleValue = [MGLStyleValue<NSValue *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.textOffset = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); } // text-optional @@ -1314,7 +1363,7 @@ MGLStyleValue<NSNumber *> *constantStyleValue = [MGLStyleValue<NSNumber *> valueWithRawValue:@0xff]; layer.textRotation = constantStyleValue; - mbgl::style::PropertyValue<float> propertyValue = { 0xff }; + mbgl::style::DataDrivenPropertyValue<float> propertyValue = { 0xff }; XCTAssertEqual(rawLayer->getTextRotate(), propertyValue, @"Setting textRotation to a constant value should update text-rotate."); XCTAssertEqualObjects(layer.textRotation, constantStyleValue, @@ -1331,6 +1380,29 @@ XCTAssertEqualObjects(layer.textRotation, functionStyleValue, @"textRotation should round-trip camera functions."); + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeExponential sourceStops:@{@18: constantStyleValue} attributeName:@"keyName" options:nil]; + layer.textRotation = functionStyleValue; + + mbgl::style::ExponentialStops<float> exponentialStops = { {{18, 0xff}}, 1.0 }; + propertyValue = mbgl::style::SourceFunction<float> { "keyName", exponentialStops }; + + XCTAssertEqual(rawLayer->getTextRotate(), propertyValue, + @"Setting textRotation to a source function should update text-rotate."); + XCTAssertEqualObjects(layer.textRotation, functionStyleValue, + @"textRotation should round-trip source functions."); + + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeExponential compositeStops:@{@10: @{@18: constantStyleValue}} attributeName:@"keyName" options:nil]; + layer.textRotation = functionStyleValue; + + std::map<float, float> innerStops { {18, 0xff} }; + mbgl::style::CompositeExponentialStops<float> compositeStops { { {10.0, innerStops} }, 1.0 }; + + propertyValue = mbgl::style::CompositeFunction<float> { "keyName", compositeStops }; + + XCTAssertEqual(rawLayer->getTextRotate(), propertyValue, + @"Setting textRotation to a composite function should update text-rotate."); + XCTAssertEqualObjects(layer.textRotation, functionStyleValue, + @"textRotation should round-trip composite functions."); layer.textRotation = nil; @@ -1338,11 +1410,6 @@ @"Unsetting textRotation should return text-rotate to the default value."); XCTAssertEqualObjects(layer.textRotation, defaultStyleValue, @"textRotation should return the default value after being unset."); - - functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.textRotation = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); - functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; - XCTAssertThrowsSpecificNamed(layer.textRotation = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); } // text-rotation-alignment diff --git a/platform/darwin/test/query-style.json b/platform/darwin/test/query-style.json deleted file mode 100644 index 97f1d04432..0000000000 --- a/platform/darwin/test/query-style.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "version": 8, - "sources": { - "source1": { - "type": "geojson", - "data": { - "type": "Point", - "coordinates": [ - 0, - 0 - ] - } - }, - "source2": { - "type": "geojson", - "data": { - "type": "Point", - "coordinates": [ - 0, - 0 - ] - } - }, - "source3": { - "type": "geojson", - "data": { - "type": "Point", - "coordinates": [ - 0, - 0 - ] - } - }, - "source4": { - "type": "geojson", - "data": { - "type": "Feature", - "id": "feature1", - "geometry": { - "type": "Point", - "coordinates": [ - 0.0, - 0.0 - ] - }, - "properties": { - "key1": "value1", - "key2": 1.5, - "key3": false, - "key4": 0.5 - } - } - }, - "source5": { - "type": "vector", - "url": "mapbox://mapbox.mapbox-streets-v6" - }, - "source6": { - "type": "raster", - "url": "mapbox://mapbox.satellite", - "tileSize": 256 - } - }, - "layers": [ - { - "id": "layer1", - "type": "symbol", - "source": "source1", - "layout": { - "icon-image": "test-icon" - } - }, - { - "id": "layer2", - "type": "symbol", - "source": "source2", - "layout": { - "icon-image": "test-icon" - } - }, - { - "id": "layer3", - "type": "symbol", - "source": "source3", - "layout": { - "icon-image": "test-icon" - } - }, - { - "id": "layer4", - "type": "symbol", - "source": "source4", - "layout": { - "icon-image": "test-icon" - } - } - ] -} |