diff --git a/CHANGELOG.md b/CHANGELOG.md index 480b991e7..f2b9191c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## v2.10.0 * Added `Matrix` API wrapper. The [Mapbox Matrix API](https://docs.mapbox.com/api/navigation/matrix/) computes travel times between many points, and returns a matrix of all travel times between the locations. [#626](https://github.com/mapbox/mapbox-directions-swift/pull/626) +* Fixed a crash that could occur if only one `Waypoint` with a nonnull `name` was used in the Directions request. [#797](https://github.com/mapbox/mapbox-directions-swift/pull/797) ## v2.9.0 diff --git a/Sources/MapboxDirections/DirectionsOptions.swift b/Sources/MapboxDirections/DirectionsOptions.swift index e6636e144..1c547dbc6 100644 --- a/Sources/MapboxDirections/DirectionsOptions.swift +++ b/Sources/MapboxDirections/DirectionsOptions.swift @@ -324,6 +324,8 @@ open class DirectionsOptions: Codable { */ var legSeparators: [Waypoint] { var waypoints = self.waypoints + guard waypoints.count > 1 else { return [] } + let source = waypoints.removeFirst() let destination = waypoints.removeLast() return [source] + waypoints.filter { $0.separatesLegs } + [destination] @@ -563,7 +565,7 @@ open class DirectionsOptions: Codable { } private var waypointNames: String? { - if waypoints.compactMap({ $0.name }).isEmpty { + guard !waypoints.compactMap({ $0.name }).isEmpty, waypoints.count > 1 else { return nil } return legSeparators.map({ $0.name ?? "" }).joined(separator: ";") diff --git a/Tests/MapboxDirectionsTests/RouteOptionsTests.swift b/Tests/MapboxDirectionsTests/RouteOptionsTests.swift index 6cde7fd04..fb4d8951a 100644 --- a/Tests/MapboxDirectionsTests/RouteOptionsTests.swift +++ b/Tests/MapboxDirectionsTests/RouteOptionsTests.swift @@ -363,12 +363,34 @@ class RouteOptionsTests: XCTestCase { let expectedIncludeQueryItem = URLQueryItem(name: "include", value: "hov2,hov3,hot") XCTAssertTrue(options.urlQueryItems.contains(expectedIncludeQueryItem)) } - - func testNoWaypointsAndOneWaypoint() { + + func testReturnPathIfNoWaypointsAndOneWaypoint() { let noWaypointOptions = RouteOptions(coordinates: []) XCTAssertEqual(noWaypointOptions.path, noWaypointOptions.abridgedPath) + let oneWaypointOptions = RouteOptions(coordinates: [LocationCoordinate2D(latitude: 0.0, longitude: 0.0)]) XCTAssertEqual(oneWaypointOptions.path, oneWaypointOptions.abridgedPath) + + let waypoints = [ + Waypoint(coordinate: LocationCoordinate2D(latitude: 0.0, longitude: 0.0), name: "name") + ] + let oneWaypointOptionsWithNonNilName = RouteOptions(waypoints: waypoints) + XCTAssertEqual(oneWaypointOptionsWithNonNilName.path, oneWaypointOptionsWithNonNilName.abridgedPath) + } + + func testReturnUrlQueryWaypoinNameItemsIfNoWaypointsAndOneWaypoint() { + let noWaypointOptions = RouteOptions(coordinates: []) + XCTAssertFalse(noWaypointOptions.urlQueryItems.map { $0.name }.contains("waypoint_names")) + + let oneWaypointOptionsWithNilName = RouteOptions(coordinates: [LocationCoordinate2D(latitude: 0.0, longitude: 0.0)]) + XCTAssertFalse(oneWaypointOptionsWithNilName.urlQueryItems.map { $0.name }.contains("waypoint_names")) + + let waypoints = [ + Waypoint(coordinate: LocationCoordinate2D(latitude: 0.0, longitude: 0.0), name: "name") + ] + + let oneWaypointOptionsWithNonNilName = RouteOptions(waypoints: waypoints) + XCTAssertFalse(oneWaypointOptionsWithNonNilName.urlQueryItems.map { $0.name }.contains("waypoint_names")) } }