342 lines
13 KiB
Swift
342 lines
13 KiB
Swift
import MapLibre
|
||
import XCTest
|
||
|
||
/**
|
||
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 MLNDocumentationGuideTests: XCTestCase, MLNMapViewDelegate {
|
||
var mapView: MLNMapView!
|
||
var styleLoadingExpectation: XCTestExpectation!
|
||
|
||
override func setUp() {
|
||
super.setUp()
|
||
let styleURL = Bundle(for: MLNDocumentationGuideTests.self).url(forResource: "one-liner", withExtension: "json")
|
||
mapView = MLNMapView(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: 10, handler: nil)
|
||
}
|
||
|
||
override func tearDown() {
|
||
mapView = nil
|
||
styleLoadingExpectation = nil
|
||
super.tearDown()
|
||
}
|
||
|
||
func mapView(_: MLNMapView, didFinishLoading _: MLNStyle) {
|
||
styleLoadingExpectation.fulfill()
|
||
}
|
||
|
||
func testMigratingToExpressions$Stops() {
|
||
// #-example-code
|
||
// Swift sample on how to populate a stepping expression with multiple stops.
|
||
// Create a color ramp.
|
||
#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
|
||
|
||
// Based on the zoom and `stops`, change the color.
|
||
var functionExpression = NSExpression(forMLNStepping: .zoomLevelVariable,
|
||
from: NSExpression(forConstantValue: stops[0]),
|
||
stops: NSExpression(forConstantValue: stops))
|
||
|
||
// Based on zoom and `stopsLineWidth`, set the Line width.
|
||
let initialValue = 4.0
|
||
let stopsLineWidth = [
|
||
11.0: initialValue,
|
||
14.0: 6.0,
|
||
20.0: 18.0,
|
||
]
|
||
|
||
functionExpression = NSExpression(
|
||
forMLNStepping: .zoomLevelVariable,
|
||
from: NSExpression(forConstantValue: initialValue),
|
||
stops: NSExpression(forConstantValue: stopsLineWidth)
|
||
)
|
||
// #-end-example-code
|
||
print(functionExpression)
|
||
print(stopsLineWidth)
|
||
}
|
||
|
||
func testMigratingToExpressions$Linear() {
|
||
// #-example-code
|
||
let url = URL(string: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson")!
|
||
let symbolSource = MLNSource(identifier: "source")
|
||
let symbolLayer = MLNSymbolStyleLayer(identifier: "place-city-sm", source: symbolSource)
|
||
|
||
let source = MLNShapeSource(identifier: "earthquakes", url: url, options: nil)
|
||
let mag = 1.0 // Update based on earthquake GeoJSON data
|
||
mapView.style?.addSource(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
|
||
|
||
let layer = MLNCircleStyleLayer(identifier: "circles", source: source)
|
||
|
||
let circleExpression: NSExpression
|
||
if #available(iOS 15, *) {
|
||
circleExpression = NSExpression(
|
||
forMLNInterpolating: NSExpression(forConstantValue: mag),
|
||
curveType: .linear,
|
||
parameters: nil,
|
||
stops: NSExpression(forConstantValue: stops)
|
||
)
|
||
} else {
|
||
// This works up to iOS 14.5
|
||
circleExpression = NSExpression(
|
||
format: "mgl_interpolate:withCurveType:parameters:stops:(mag, 'linear', nil, %@)",
|
||
stops
|
||
)
|
||
}
|
||
|
||
layer.circleColor = circleExpression
|
||
layer.circleRadius = NSExpression(forConstantValue: 10)
|
||
mapView.style?.insertLayer(layer, below: symbolLayer)
|
||
// #-end-example-code
|
||
print(circleExpression)
|
||
}
|
||
|
||
func testMigratingToExpressions$LinearConvenience() {
|
||
let source = MLNShapeSource(identifier: "circles", shape: nil, options: nil)
|
||
let layer = MLNCircleStyleLayer(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(forMLNInterpolating: 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 = MLNShapeSource(identifier: "circles", shape: nil, options: nil)
|
||
let layer = MLNCircleStyleLayer(identifier: "circles", source: source)
|
||
|
||
// #-example-code
|
||
let stops = [
|
||
12: 0.5,
|
||
14: 2,
|
||
18: 18,
|
||
]
|
||
|
||
layer.circleRadius = NSExpression(forMLNInterpolating: .zoomLevelVariable,
|
||
curveType: .exponential,
|
||
parameters: NSExpression(forConstantValue: 1.5),
|
||
stops: NSExpression(forConstantValue: stops))
|
||
// #-end-example-code
|
||
}
|
||
|
||
func testMigratingToExpressions$ExponentialConvenience() {
|
||
let source = MLNShapeSource(identifier: "circles", shape: nil, options: nil)
|
||
let layer = MLNCircleStyleLayer(identifier: "circles", source: source)
|
||
|
||
// #-example-code
|
||
let stops = [
|
||
12: 0.5,
|
||
14: 2,
|
||
18: 18,
|
||
]
|
||
|
||
layer.circleRadius = NSExpression(forMLNInterpolating: NSExpression.zoomLevelVariable, curveType: MLNExpressionInterpolationMode.exponential, parameters: NSExpression(forConstantValue: 1.5), stops: NSExpression(forConstantValue: stops))
|
||
// #-end-example-code
|
||
}
|
||
|
||
func testMigratingToExpressions$Interval() {
|
||
let source = MLNShapeSource(identifier: "circles", shape: nil, options: nil)
|
||
let layer = MLNCircleStyleLayer(identifier: "circles", source: source)
|
||
|
||
// #-example-code
|
||
#if os(macOS)
|
||
let stops: [NSNumber: NSColor] = [
|
||
0: .yellow,
|
||
2.5: .orange,
|
||
5: .red,
|
||
7.5: .blue,
|
||
10: .white,
|
||
]
|
||
|
||
layer.circleColor = NSExpression(forMLNStepping: .zoomLevelVariable,
|
||
from: NSExpression(forConstantValue: NSColor.green),
|
||
stops: NSExpression(forConstantValue: stops))
|
||
#else
|
||
let stops: [NSNumber: UIColor] = [
|
||
0: .yellow,
|
||
2.5: .orange,
|
||
5: .red,
|
||
7.5: .blue,
|
||
10: .white,
|
||
]
|
||
|
||
layer.circleColor = NSExpression(forMLNStepping: .zoomLevelVariable,
|
||
from: NSExpression(forConstantValue: UIColor.green),
|
||
stops: NSExpression(forConstantValue: stops))
|
||
#endif
|
||
// #-end-example-code
|
||
}
|
||
|
||
func testMigratingToExpressions$Categorical() {
|
||
let source = MLNShapeSource(identifier: "circles", shape: nil, options: nil)
|
||
let layer = MLNCircleStyleLayer(identifier: "circles", source: source)
|
||
|
||
// #-example-code
|
||
// Category type
|
||
let type = NSExpression(forConstantValue: "type")
|
||
|
||
// Categories
|
||
let earthquake = NSExpression(forConstantValue: "earthquake")
|
||
let explosion = NSExpression(forConstantValue: "explosion")
|
||
let quarryBlast = NSExpression(forConstantValue: "quarry blast")
|
||
|
||
#if os(macOS)
|
||
let defaultColor = NSExpression(forConstantValue: NSColor.blue)
|
||
let orange = NSExpression(forConstantValue: NSColor.orange)
|
||
let red = NSExpression(forConstantValue: NSColor.red)
|
||
let yellow = NSExpression(forConstantValue: NSColor.yellow)
|
||
|
||
layer.circleColor = NSExpression(forMLNMatchingKey: type,
|
||
in: [earthquake: orange, explosion: red, quarryBlast: yellow],
|
||
default: defaultColor)
|
||
#else
|
||
let defaultColor = NSExpression(forConstantValue: UIColor.blue)
|
||
let orange = NSExpression(forConstantValue: UIColor.orange)
|
||
let red = NSExpression(forConstantValue: UIColor.red)
|
||
let yellow = NSExpression(forConstantValue: UIColor.yellow)
|
||
|
||
XCTExpectFailure("Awaiting unit test refactoring for https://github.com/maplibre/maplibre-native/issues/331")
|
||
layer.circleColor = NSExpression(forMLNMatchingKey: type,
|
||
in: [earthquake: orange, explosion: red, quarryBlast: yellow],
|
||
default: defaultColor)
|
||
#endif
|
||
// #-end-example-code
|
||
}
|
||
|
||
func testMigratingToExpressions$CategoricalValue() {
|
||
let source = MLNShapeSource(identifier: "circles", shape: nil, options: nil)
|
||
let layer = MLNCircleStyleLayer(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: "FUNCTION(%@, 'valueForKeyPath:', type)",
|
||
stops
|
||
)
|
||
#endif
|
||
// #-end-example-code
|
||
}
|
||
|
||
func testMigratingToExpressions$Identity() {
|
||
let source = MLNShapeSource(identifier: "circles", shape: nil, options: nil)
|
||
let layer = MLNCircleStyleLayer(identifier: "circles", source: source)
|
||
|
||
// #-example-code
|
||
layer.circleRadius = NSExpression(forKeyPath: "mag")
|
||
// #-end-example-code
|
||
}
|
||
|
||
func testMigratingToExpressions$Multiply() {
|
||
let source = MLNShapeSource(identifier: "circles", shape: nil, options: nil)
|
||
let layer = MLNCircleStyleLayer(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 = MLNShapeSource(identifier: "circles", shape: nil, options: nil)
|
||
|
||
// #-example-code
|
||
let magnitudeLayer = MLNSymbolStyleLayer(identifier: "mag-layer", source: source)
|
||
magnitudeLayer.text = NSExpression(format: "CAST(mag, 'NSString')")
|
||
mapView.style?.addLayer(magnitudeLayer)
|
||
// #-end-example-code
|
||
}
|
||
|
||
// MARK: Swift Example Code for Expected Failures
|
||
|
||
func testExpectPassSwift() {
|
||
XCTAssertNotNil(1)
|
||
}
|
||
|
||
/// https://developer.apple.com/documentation/xctest/expected_failures
|
||
func testExpectFailureSwift() {
|
||
XCTExpectFailure("Swift example - Anticipate known test failures to prevent failing tests from affecting your workflows.")
|
||
XCTAssertNotNil(nil)
|
||
}
|
||
}
|