From 6f41b5ef7d2640d839b40d4cf081652f7cfe8afc Mon Sep 17 00:00:00 2001 From: jill-cardamon <43434254+jill-cardamon@users.noreply.github.com> Date: Wed, 2 Feb 2022 08:57:40 -0800 Subject: [PATCH] Fix backwards incompatible associated value in shield implementation (#647) * Fix backwards incompatible shield implementation. * Include PR in changelog. * Change code property back to text. --- CHANGELOG.md | 2 +- .../VisualInstructionComponent.swift | 26 ++++++++------- .../VisualInstructionComponentTests.swift | 33 +++++++++---------- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af225baeb..aa125ff4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## v2.3.0 -* Added `VisualInstruction.Component.ShieldRepresentation` struct for displaying a highway shield. Renamed `VisualInstruction.Component.image(image:alternativeText:)` to `VisualInstruction.Component.image(image:alternativeText:shield:)`. ([#644](https://github.com/mapbox/mapbox-directions-swift/pull/644)) +* Added `VisualInstruction.Component.ShieldRepresentation` struct for displaying a highway shield. Added `VisualInstruction.Component.ImageRepresentation.shield` property. ([#644](https://github.com/mapbox/mapbox-directions-swift/pull/644), [#647](https://github.com/mapbox/mapbox-directions-swift/pull/647)) ## v2.2.0 diff --git a/Sources/MapboxDirections/VisualInstructionComponent.swift b/Sources/MapboxDirections/VisualInstructionComponent.swift index 9b74904bc..22ecfe073 100644 --- a/Sources/MapboxDirections/VisualInstructionComponent.swift +++ b/Sources/MapboxDirections/VisualInstructionComponent.swift @@ -45,9 +45,8 @@ public extension VisualInstruction { - parameter image: The component’s preferred image representation. - parameter alternativeText: The component’s alternative text representation. Use this representation if the image representation is unavailable or unusable, but consider formatting the text in a special way to distinguish it from an ordinary `.text` component. - - parameter shield: Optionally, a structured image representation for displaying a [highway shield](https://en.wikipedia.org/wiki/Highway_shield). */ - case image(image: ImageRepresentation, alternativeText: TextRepresentation, shield: ShieldRepresentation? = nil) + case image(image: ImageRepresentation, alternativeText: TextRepresentation) /** The component is an image of a zoomed junction, with a fallback text representation. @@ -128,8 +127,9 @@ public extension VisualInstruction.Component { /** Initializes an image representation bearing the image at the given base URL. */ - public init(imageBaseURL: URL?) { + public init(imageBaseURL: URL?, shield: ShieldRepresentation? = nil) { self.imageBaseURL = imageBaseURL + self.shield = shield } /** @@ -137,6 +137,11 @@ public extension VisualInstruction.Component { */ public let imageBaseURL: URL? + /** + Optionally, a structured image representation for displaying a [highway shield](https://en.wikipedia.org/wiki/Highway_shield). + */ + public let shield: ShieldRepresentation? + /** Returns a remote URL to the image file that represents the component. @@ -286,7 +291,6 @@ extension VisualInstruction.Component: Codable { let abbreviation = try container.decodeIfPresent(String.self, forKey: .abbreviatedText) let abbreviationPriority = try container.decodeIfPresent(Int.self, forKey: .abbreviatedTextPriority) let textRepresentation = TextRepresentation(text: text, abbreviation: abbreviation, abbreviationPriority: abbreviationPriority) - let shieldRepresentation = try container.decodeIfPresent(ShieldRepresentation.self, forKey: .shield) switch kind { case .delimiter: @@ -298,8 +302,9 @@ extension VisualInstruction.Component: Codable { if let imageBaseURLString = try container.decodeIfPresent(String.self, forKey: .imageBaseURL) { imageBaseURL = URL(string: imageBaseURLString) } - let imageRepresentation = ImageRepresentation(imageBaseURL: imageBaseURL) - self = .image(image: imageRepresentation, alternativeText: textRepresentation, shield: shieldRepresentation) + let shieldRepresentation = try container.decodeIfPresent(ShieldRepresentation.self, forKey: .shield) + let imageRepresentation = ImageRepresentation(imageBaseURL: imageBaseURL, shield: shieldRepresentation) + self = .image(image: imageRepresentation, alternativeText: textRepresentation) case .exit: self = .exit(text: textRepresentation) case .exitCode: @@ -327,11 +332,11 @@ extension VisualInstruction.Component: Codable { case .text(let text): try container.encode(Kind.text, forKey: .kind) textRepresentation = text - case .image(let image, let alternativeText, let shield): + case .image(let image, let alternativeText): try container.encode(Kind.image, forKey: .kind) textRepresentation = alternativeText try container.encodeIfPresent(image.imageBaseURL?.absoluteString, forKey: .imageBaseURL) - try container.encodeIfPresent(shield, forKey: .shield) + try container.encodeIfPresent(image.shield, forKey: .shield) case .exit(let text): try container.encode(Kind.exit, forKey: .kind) textRepresentation = text @@ -366,11 +371,10 @@ extension VisualInstruction.Component: Equatable { (let .exit(lhsText), let .exit(rhsText)), (let .exitCode(lhsText), let .exitCode(rhsText)): return lhsText == rhsText - case (let .image(lhsURL, lhsAlternativeText, lhsShield), - let .image(rhsURL, rhsAlternativeText, rhsShield)): + case (let .image(lhsURL, lhsAlternativeText), + let .image(rhsURL, rhsAlternativeText)): return lhsURL == rhsURL && lhsAlternativeText == rhsAlternativeText - && lhsShield == rhsShield case (let .guidanceView(lhsURL, lhsAlternativeText), let .guidanceView(rhsURL, rhsAlternativeText)): return lhsURL == rhsURL diff --git a/Tests/MapboxDirectionsTests/VisualInstructionComponentTests.swift b/Tests/MapboxDirectionsTests/VisualInstructionComponentTests.swift index c3bb77293..db2dbe0a3 100644 --- a/Tests/MapboxDirectionsTests/VisualInstructionComponentTests.swift +++ b/Tests/MapboxDirectionsTests/VisualInstructionComponentTests.swift @@ -40,7 +40,7 @@ class VisualInstructionComponentTests: XCTestCase { XCTAssertNotNil(component) if let component = component { switch component { - case .image(let image, let alternativeText, let shield): + case .image(let image, let alternativeText): XCTAssertEqual(image.imageBaseURL?.absoluteString, "https://s3.amazonaws.com/mapbox/shields/v3/i-95") XCTAssertEqual(image.imageURL(scale: 1, format: .svg)?.absoluteString, "https://s3.amazonaws.com/mapbox/shields/v3/i-95@1x.svg") XCTAssertEqual(image.imageURL(scale: 3, format: .svg)?.absoluteString, "https://s3.amazonaws.com/mapbox/shields/v3/i-95@3x.svg") @@ -48,18 +48,17 @@ class VisualInstructionComponentTests: XCTestCase { XCTAssertEqual(alternativeText.text, "I 95") XCTAssertNil(alternativeText.abbreviation) XCTAssertNil(alternativeText.abbreviationPriority) - XCTAssertEqual(shield?.baseURL, URL(string: "https://api.mapbox.com/styles/v1/")!) - XCTAssertEqual(shield?.name, "us-interstate") - XCTAssertEqual(shield?.textColor, "white") - XCTAssertEqual(shield?.text, "95") + XCTAssertEqual(image.shield?.baseURL, URL(string: "https://api.mapbox.com/styles/v1/")!) + XCTAssertEqual(image.shield?.name, "us-interstate") + XCTAssertEqual(image.shield?.textColor, "white") + XCTAssertEqual(image.shield?.text, "95") default: XCTFail("Image component should not be decoded as any other kind of component.") } } - - component = .image(image: .init(imageBaseURL: URL(string: "https://s3.amazonaws.com/mapbox/shields/v3/i-95")!), - alternativeText: .init(text: "I 95", abbreviation: nil, abbreviationPriority: nil), - shield: .init(baseURL: URL(string: "https://api.mapbox.com/styles/v1/")!, name: "us-interstate", textColor: "white", text: "95")) + let shield = VisualInstruction.Component.ShieldRepresentation(baseURL: URL(string: "https://api.mapbox.com/styles/v1/")!, name: "us-interstate", textColor: "white", text: "95") + component = .image(image: .init(imageBaseURL: URL(string: "https://s3.amazonaws.com/mapbox/shields/v3/i-95")!, shield: shield), + alternativeText: .init(text: "I 95", abbreviation: nil, abbreviationPriority: nil)) let encoder = JSONEncoder() var encodedData: Data? XCTAssertNoThrow(encodedData = try encoder.encode(component)) @@ -126,23 +125,23 @@ class VisualInstructionComponentTests: XCTestCase { XCTAssertNotNil(component) if let component = component { switch component { - case .image(let image, let alternativeText, let shield): + case .image(let image, let alternativeText): XCTAssertNil(image.imageBaseURL?.absoluteString) XCTAssertEqual(alternativeText.text, "I 95") XCTAssertNil(alternativeText.abbreviation) XCTAssertNil(alternativeText.abbreviationPriority) - XCTAssertEqual(shield?.baseURL, URL(string: "https://api.mapbox.com/styles/v1/")!) - XCTAssertEqual(shield?.name, "us-interstate") - XCTAssertEqual(shield?.textColor, "white") - XCTAssertEqual(shield?.text, "95") + XCTAssertEqual(image.shield?.baseURL, URL(string: "https://api.mapbox.com/styles/v1/")!) + XCTAssertEqual(image.shield?.name, "us-interstate") + XCTAssertEqual(image.shield?.textColor, "white") + XCTAssertEqual(image.shield?.text, "95") default: XCTFail("Image component should not be decoded as any other kind of component.") } } - component = .image(image: .init(imageBaseURL: nil), - alternativeText: .init(text: "I 95", abbreviation: nil, abbreviationPriority: nil), - shield: .init(baseURL: URL(string: "https://api.mapbox.com/styles/v1/")!, name: "us-interstate", textColor: "white", text: "95")) + let shield = VisualInstruction.Component.ShieldRepresentation(baseURL: URL(string: "https://api.mapbox.com/styles/v1/")!, name: "us-interstate", textColor: "white", text: "95") + component = .image(image: .init(imageBaseURL: nil, shield: shield), + alternativeText: .init(text: "I 95", abbreviation: nil, abbreviationPriority: nil)) let encoder = JSONEncoder() var encodedData: Data? XCTAssertNoThrow(encodedData = try encoder.encode(component))