270 lines
11 KiB
Swift
270 lines
11 KiB
Swift
import XCTest
|
|
import Mapbox
|
|
#if os(iOS)
|
|
import UIKit
|
|
#else
|
|
import Cocoa
|
|
#endif
|
|
|
|
/**
|
|
Test cases that ensure the inline examples in the project documentation
|
|
compile.
|
|
|
|
To add an example:
|
|
1. Add a test case named in the form testMGLClass or testMGLClass$method.
|
|
2. Wrap the code you'd like to appear in the documentation within the
|
|
following comment blocks:
|
|
```
|
|
//#-example-code
|
|
...
|
|
//#-end-example-code
|
|
```
|
|
3. Insert an empty Swift code block inside the header file where you'd like the
|
|
example code to be inserted.
|
|
4. Run `make darwin-update-examples` to extract example code from the test
|
|
method below and insert it into the header.
|
|
*/
|
|
class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate {
|
|
var mapView: MGLMapView!
|
|
var styleLoadingExpectation: XCTestExpectation!
|
|
|
|
override func setUp() {
|
|
super.setUp()
|
|
let styleURL = Bundle(for: MGLDocumentationExampleTests.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 testMGLShape$shapeWithData_encoding_error_() {
|
|
let mainBundle = Bundle(for: MGLDocumentationExampleTests.self)
|
|
|
|
//#-example-code
|
|
let url = mainBundle.url(forResource: "amsterdam", withExtension: "geojson")!
|
|
let data = try! Data(contentsOf: url)
|
|
let feature = try! MGLShape(data: data, encoding: String.Encoding.utf8.rawValue) as! MGLShapeCollectionFeature
|
|
//#-end-example-code
|
|
|
|
XCTAssertNotNil(feature.shapes.first as? MGLPolygonFeature)
|
|
}
|
|
|
|
func testMGLShapeSource() {
|
|
//#-example-code
|
|
var coordinates: [CLLocationCoordinate2D] = [
|
|
CLLocationCoordinate2D(latitude: 37.77, longitude: -122.42),
|
|
CLLocationCoordinate2D(latitude: 38.91, longitude: -77.04),
|
|
]
|
|
let polyline = MGLPolylineFeature(coordinates: &coordinates, count: UInt(coordinates.count))
|
|
let source = MGLShapeSource(identifier: "lines", features: [polyline], options: nil)
|
|
mapView.style?.addSource(source)
|
|
//#-end-example-code
|
|
|
|
XCTAssertNotNil(mapView.style?.source(withIdentifier: "lines"))
|
|
}
|
|
|
|
func testMGLRasterSource() {
|
|
//#-example-code
|
|
let source = MGLRasterSource(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"))
|
|
]
|
|
])
|
|
mapView.style?.addSource(source)
|
|
//#-end-example-code
|
|
|
|
XCTAssertNotNil(mapView.style?.source(withIdentifier: "clouds"))
|
|
}
|
|
|
|
func testMGLVectorSource() {
|
|
//#-example-code
|
|
let source = MGLVectorSource(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"))
|
|
]
|
|
])
|
|
mapView.style?.addSource(source)
|
|
//#-end-example-code
|
|
|
|
XCTAssertNotNil(mapView.style?.source(withIdentifier: "pois"))
|
|
}
|
|
|
|
func testMGLPolyline() {
|
|
//#-example-code
|
|
let coordinates = [
|
|
CLLocationCoordinate2D(latitude: 35.68476, longitude: -220.24257),
|
|
CLLocationCoordinate2D(latitude: 37.78428, longitude: -122.41310)
|
|
]
|
|
let polyline = MGLPolyline(coordinates: coordinates, count: UInt(coordinates.count))
|
|
//#-end-example-code
|
|
|
|
XCTAssertNotNil(polyline)
|
|
}
|
|
|
|
func testMGLCircleStyleLayer() {
|
|
let population = MGLVectorSource(identifier: "population", configurationURL: URL(string: "https://example.com/style.json")!)
|
|
mapView.style?.addSource(population)
|
|
|
|
//#-example-code
|
|
let layer = MGLCircleStyleLayer(identifier: "circles", source: population)
|
|
layer.sourceLayerIdentifier = "population"
|
|
layer.circleColor = MGLStyleValue(rawValue: .green)
|
|
layer.circleRadius = MGLStyleValue(interpolationMode: .exponential,
|
|
cameraStops: [12: MGLStyleValue(rawValue: 2),
|
|
22: MGLStyleValue(rawValue: 180)],
|
|
options: [.interpolationBase: 1.75])
|
|
layer.circleOpacity = MGLStyleValue(rawValue: 0.7)
|
|
layer.predicate = NSPredicate(format: "%K == %@", "marital-status", "married")
|
|
mapView.style?.addLayer(layer)
|
|
//#-end-example-code
|
|
|
|
XCTAssertNotNil(mapView.style?.layer(withIdentifier: "circles"))
|
|
}
|
|
|
|
func testMGLLineStyleLayer() {
|
|
let trails = MGLVectorSource(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 = MGLStyleValue(interpolationMode: .exponential,
|
|
cameraStops: [14: MGLStyleValue(rawValue: 2),
|
|
18: MGLStyleValue(rawValue: 20)],
|
|
options: [.interpolationBase: 1.5])
|
|
layer.lineColor = MGLStyleValue(rawValue: .brown)
|
|
layer.lineCap = MGLStyleValue(rawValue: NSValue(mglLineCap: .round))
|
|
layer.predicate = NSPredicate(format: "%K == %@", "trail-type", "mountain-biking")
|
|
mapView.style?.addLayer(layer)
|
|
//#-end-example-code
|
|
|
|
XCTAssertNotNil(mapView.style?.layer(withIdentifier: "trails-path"))
|
|
}
|
|
|
|
func testMGLFillStyleLayer() {
|
|
let parks = MGLVectorSource(identifier: "parks", configurationURL: URL(string: "https://example.com/style.json")!)
|
|
mapView.style?.addSource(parks)
|
|
|
|
//#-example-code
|
|
let layer = MGLFillStyleLayer(identifier: "parks", source: parks)
|
|
layer.sourceLayerIdentifier = "parks"
|
|
layer.fillColor = MGLStyleValue(rawValue: .green)
|
|
layer.predicate = NSPredicate(format: "type == %@", "national-park")
|
|
mapView.style?.addLayer(layer)
|
|
//#-end-example-code
|
|
|
|
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")!)
|
|
mapView.style?.addSource(pois)
|
|
|
|
//#-example-code
|
|
let layer = MGLSymbolStyleLayer(identifier: "coffeeshops", source: pois)
|
|
layer.sourceLayerIdentifier = "pois"
|
|
layer.iconImageName = MGLStyleValue(rawValue: "coffee")
|
|
layer.iconScale = MGLStyleValue(rawValue: 0.5)
|
|
layer.text = MGLStyleValue(rawValue: "{name}")
|
|
#if os(macOS)
|
|
var vector = CGVector(dx: 10, dy: 0)
|
|
layer.textTranslation = MGLStyleValue(rawValue: NSValue(bytes: &vector, objCType: "{CGVector=dd}"))
|
|
#else
|
|
layer.textTranslation = MGLStyleValue(rawValue: NSValue(cgVector: CGVector(dx: 10, dy: 0)))
|
|
#endif
|
|
layer.textJustification = MGLStyleValue(rawValue: NSValue(mglTextJustification: .left))
|
|
layer.textAnchor = MGLStyleValue(rawValue: NSValue(mglTextAnchor: .left))
|
|
layer.predicate = NSPredicate(format: "%K == %@", "venue-type", "coffee")
|
|
mapView.style?.addLayer(layer)
|
|
//#-end-example-code
|
|
|
|
XCTAssertNotNil(mapView.style?.layer(withIdentifier: "coffeeshops"))
|
|
}
|
|
|
|
func testMGLRasterStyleLayer() {
|
|
let source = MGLRasterSource(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"))
|
|
]
|
|
])
|
|
mapView.style?.addSource(source)
|
|
|
|
//#-example-code
|
|
let layer = MGLRasterStyleLayer(identifier: "clouds", source: source)
|
|
layer.rasterOpacity = MGLStyleValue(rawValue: 0.5)
|
|
mapView.style?.addLayer(layer)
|
|
//#-end-example-code
|
|
|
|
XCTAssertNotNil(mapView.style?.layer(withIdentifier: "clouds"))
|
|
}
|
|
|
|
func testMGLVectorStyleLayer$predicate() {
|
|
let terrain = MGLVectorSource(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")
|
|
mapView.style?.addLayer(layer)
|
|
//#-end-example-code
|
|
|
|
XCTAssertNotNil(mapView.style?.layer(withIdentifier: "contour"))
|
|
}
|
|
|
|
func testMGLMapView() {
|
|
//#-example-code
|
|
#if os(macOS)
|
|
class MapClickGestureRecognizer: NSClickGestureRecognizer {
|
|
override func shouldRequireFailure(of otherGestureRecognizer: NSGestureRecognizer) -> Bool {
|
|
return otherGestureRecognizer is NSClickGestureRecognizer
|
|
}
|
|
}
|
|
#else
|
|
let mapTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(myCustomFunction))
|
|
for recognizer in mapView.gestureRecognizers! where recognizer is UITapGestureRecognizer {
|
|
mapTapGestureRecognizer.require(toFail: recognizer)
|
|
}
|
|
mapView.addGestureRecognizer(mapTapGestureRecognizer)
|
|
#endif
|
|
//#-end-example-code
|
|
}
|
|
|
|
// For testMGLMapView().
|
|
func myCustomFunction() {}
|
|
}
|