diff --git a/Sources/SwiftDocC/Model/Rendering/DocumentationContentRenderer.swift b/Sources/SwiftDocC/Model/Rendering/DocumentationContentRenderer.swift index 8a99f9d5c7..f6cf7a5613 100644 --- a/Sources/SwiftDocC/Model/Rendering/DocumentationContentRenderer.swift +++ b/Sources/SwiftDocC/Model/Rendering/DocumentationContentRenderer.swift @@ -230,7 +230,7 @@ public class DocumentationContentRenderer { } // Verify that the current platform is in beta and the version number matches the introduced platform version. - guard current.beta && VersionTriplet(semanticVersion: introduced) == current.version else { + guard current.beta && SemanticVersion(introduced).isEqualToVersionTriplet(current.version) else { return false } } diff --git a/Sources/SwiftDocC/Model/Rendering/Symbol/AvailabilityRenderMetadataItem.swift b/Sources/SwiftDocC/Model/Rendering/Symbol/AvailabilityRenderMetadataItem.swift index 7cdea41139..48ea3416e9 100644 --- a/Sources/SwiftDocC/Model/Rendering/Symbol/AvailabilityRenderMetadataItem.swift +++ b/Sources/SwiftDocC/Model/Rendering/Symbol/AvailabilityRenderMetadataItem.swift @@ -11,7 +11,7 @@ import Foundation import SymbolKit -extension VersionTriplet { +extension SemanticVersion { enum Precision: Int { case all = 0, patch, minor @@ -45,10 +45,21 @@ extension VersionTriplet { .joined(separator: ".") } - init(semanticVersion: SymbolGraph.SemanticVersion) { + init(_ semanticVersion: SymbolGraph.SemanticVersion) { self.major = semanticVersion.major self.minor = semanticVersion.minor self.patch = semanticVersion.patch + self.prerelease = semanticVersion.prerelease + self.buildMetadata = semanticVersion.buildMetadata + } + + /// Compares a version triplet to a semantic version. + /// - Parameter version: A version triplet to compare to this semantic version. + /// - Returns: Returns whether the given triple represents the same version as the current version. + func isEqualToVersionTriplet(_ version: VersionTriplet) -> Bool { + return major == version.major && + minor == version.minor && + patch == version.patch } } @@ -123,10 +134,10 @@ public struct AvailabilityRenderItem: Codable, Hashable, Equatable { let platformName = availability.domain.map({ PlatformName(operatingSystemName: $0.rawValue) }) name = platformName?.displayName - let introducedVersion = availability.introducedVersion.flatMap { VersionTriplet(semanticVersion: $0) } + let introducedVersion = availability.introducedVersion.flatMap { SemanticVersion($0) } introduced = introducedVersion?.stringRepresentation(precisionUpToNonsignificant: .minor) - deprecated = availability.deprecatedVersion.flatMap { VersionTriplet(semanticVersion: $0).stringRepresentation(precisionUpToNonsignificant: .minor) } - obsoleted = availability.obsoletedVersion.flatMap { VersionTriplet(semanticVersion: $0).stringRepresentation(precisionUpToNonsignificant: .minor) } + deprecated = availability.deprecatedVersion.flatMap { SemanticVersion($0).stringRepresentation(precisionUpToNonsignificant: .minor) } + obsoleted = availability.obsoletedVersion.flatMap { SemanticVersion($0).stringRepresentation(precisionUpToNonsignificant: .minor) } message = availability.message renamed = availability.renamed unconditionallyUnavailable = availability.isUnconditionallyUnavailable @@ -144,8 +155,8 @@ public struct AvailabilityRenderItem: Codable, Hashable, Equatable { isBeta = AvailabilityRenderItem.isBeta(introduced: availability.introduced, current: current) } - private static func isBeta(introduced: VersionTriplet?, current: PlatformVersion?) -> Bool { - guard let introduced, let current, current.beta, introduced == current.version else { + private static func isBeta(introduced: SemanticVersion?, current: PlatformVersion?) -> Bool { + guard let introduced, let current, current.beta, introduced.isEqualToVersionTriplet(current.version) else { return false } diff --git a/Sources/SwiftDocC/Semantics/Metadata/Availability.swift b/Sources/SwiftDocC/Semantics/Metadata/Availability.swift index a14c2fa2f7..ac73de9d0a 100644 --- a/Sources/SwiftDocC/Semantics/Metadata/Availability.swift +++ b/Sources/SwiftDocC/Semantics/Metadata/Availability.swift @@ -102,7 +102,7 @@ extension Metadata { /// The platform version that this page applies to. @DirectiveArgumentWrapped - public var introduced: VersionTriplet + public var introduced: SemanticVersion // FIXME: `isBeta` and `isDeprecated` properties/arguments // cf. https://github.com/apple/swift-docc/issues/441 @@ -121,17 +121,17 @@ extension Metadata { } } -extension VersionTriplet: DirectiveArgumentValueConvertible { +extension SemanticVersion: DirectiveArgumentValueConvertible { static let separator = "." init?(rawDirectiveArgumentValue: String) { - guard !rawDirectiveArgumentValue.hasSuffix(VersionTriplet.separator), - !rawDirectiveArgumentValue.hasPrefix(VersionTriplet.separator) else { + guard !rawDirectiveArgumentValue.hasSuffix(Self.separator), + !rawDirectiveArgumentValue.hasPrefix(Self.separator) else { return nil } // Split the string into major, minor and patch components - let availabilityComponents = rawDirectiveArgumentValue.split(separator: .init(VersionTriplet.separator), maxSplits: 2) + let availabilityComponents = rawDirectiveArgumentValue.split(separator: .init(Self.separator), maxSplits: 2) guard !availabilityComponents.isEmpty else { return nil } diff --git a/Tests/SwiftDocCTests/Infrastructure/VersionTripletTests.swift b/Tests/SwiftDocCTests/Infrastructure/VersionTripletTests.swift index d3bad19ddf..42eb05c1fd 100644 --- a/Tests/SwiftDocCTests/Infrastructure/VersionTripletTests.swift +++ b/Tests/SwiftDocCTests/Infrastructure/VersionTripletTests.swift @@ -24,33 +24,5 @@ class VersionTripletTests: XCTestCase { // Test the autogenerated equality conformance for coherence XCTAssertEqual(VersionTriplet(5,2,1), VersionTriplet(5,2,1)) - } - - func testStringRepresentation() { - let oneComponent = VersionTriplet(1, 0, 0) - - XCTAssertEqual(oneComponent.stringRepresentation(precisionUpToNonsignificant: .minor), "1.0") - XCTAssertEqual(oneComponent.stringRepresentation(precisionUpToNonsignificant: .patch), "1.0.0") - XCTAssertEqual(oneComponent.stringRepresentation(precisionUpToNonsignificant: .all), "1.0.0") - - let twoComponents = VersionTriplet(1, 2, 0) - XCTAssertEqual(twoComponents.stringRepresentation(precisionUpToNonsignificant: .minor), "1.2") - XCTAssertEqual(twoComponents.stringRepresentation(precisionUpToNonsignificant: .patch), "1.2.0") - XCTAssertEqual(twoComponents.stringRepresentation(precisionUpToNonsignificant: .all), "1.2.0") - - let threeComponents = VersionTriplet(1, 2, 3) - XCTAssertEqual(threeComponents.stringRepresentation(precisionUpToNonsignificant: .minor), "1.2.3") - XCTAssertEqual(threeComponents.stringRepresentation(precisionUpToNonsignificant: .patch), "1.2.3") - XCTAssertEqual(threeComponents.stringRepresentation(precisionUpToNonsignificant: .all), "1.2.3") - - let zeroVersion = VersionTriplet(0, 0, 0) - XCTAssertEqual(zeroVersion.stringRepresentation(precisionUpToNonsignificant: .minor), "0.0") - XCTAssertEqual(zeroVersion.stringRepresentation(precisionUpToNonsignificant: .patch), "0.0.0") - XCTAssertEqual(zeroVersion.stringRepresentation(precisionUpToNonsignificant: .all), "0.0.0") - - let zeroMinorVersion = VersionTriplet(1, 0, 1) - XCTAssertEqual(zeroMinorVersion.stringRepresentation(precisionUpToNonsignificant: .minor), "1.0.1") - XCTAssertEqual(zeroMinorVersion.stringRepresentation(precisionUpToNonsignificant: .patch), "1.0.1") - XCTAssertEqual(zeroMinorVersion.stringRepresentation(precisionUpToNonsignificant: .all), "1.0.1") - } + } } diff --git a/Tests/SwiftDocCTests/Model/SemaToRenderNodeTests.swift b/Tests/SwiftDocCTests/Model/SemaToRenderNodeTests.swift index 0eee12192b..dd6622586d 100644 --- a/Tests/SwiftDocCTests/Model/SemaToRenderNodeTests.swift +++ b/Tests/SwiftDocCTests/Model/SemaToRenderNodeTests.swift @@ -1566,7 +1566,7 @@ class SemaToRenderNodeTests: XCTestCase { let platforms = (renderNode.metadata.platforms ?? []).sorted(by: { lhs, rhs in lhs.name! < rhs.name! }) XCTAssertEqual(platforms.count,6) - let versionString = VersionTriplet(semanticVersion: version).stringRepresentation(precisionUpToNonsignificant: .patch) + let versionString = SemanticVersion(version).stringRepresentation(precisionUpToNonsignificant: .patch) XCTAssertEqual(platforms[0].name, "Mac Catalyst") XCTAssertEqual(platforms[0].introduced, versionString) diff --git a/Tests/SwiftDocCTests/Rendering/SemanticVersionStringRepresentationTests.swift b/Tests/SwiftDocCTests/Rendering/SemanticVersionStringRepresentationTests.swift index 05e1aec8b1..0dfda10a6d 100644 --- a/Tests/SwiftDocCTests/Rendering/SemanticVersionStringRepresentationTests.swift +++ b/Tests/SwiftDocCTests/Rendering/SemanticVersionStringRepresentationTests.swift @@ -16,18 +16,47 @@ import SymbolKit class SemanticVersionStringRepresentationTests: XCTestCase { func testConversionToVersionTriplet() { let symbolOne = SymbolGraph.SemanticVersion(major: 1, minor: 0, patch: 0) - XCTAssertEqual(VersionTriplet(semanticVersion: symbolOne), VersionTriplet(1, 0, 0)) + XCTAssertEqual(SemanticVersion(symbolOne), SemanticVersion(major: 1, minor: 0, patch: 0)) let symbolTwo = SymbolGraph.SemanticVersion(major: 1, minor: 2, patch: 0) - XCTAssertEqual(VersionTriplet(semanticVersion: symbolTwo), VersionTriplet(1, 2, 0)) + XCTAssertEqual(SemanticVersion(symbolTwo), SemanticVersion(major: 1, minor: 2, patch: 0)) let symbolThree = SymbolGraph.SemanticVersion(major: 1, minor: 2, patch: 3) - XCTAssertEqual(VersionTriplet(semanticVersion: symbolThree), VersionTriplet(1, 2, 3)) + XCTAssertEqual(SemanticVersion(symbolThree), SemanticVersion(major: 1, minor: 2, patch: 3)) let symbolFour = SymbolGraph.SemanticVersion(major: 0, minor: 0, patch: 0) - XCTAssertEqual(VersionTriplet(semanticVersion: symbolFour), VersionTriplet(0, 0, 0)) + XCTAssertEqual(SemanticVersion(symbolFour), SemanticVersion(major: 0, minor: 0, patch: 0)) let symbolFive = SymbolGraph.SemanticVersion(major: 1, minor: 0, patch: 1) - XCTAssertEqual(VersionTriplet(semanticVersion: symbolFive), VersionTriplet(1, 0, 1)) + XCTAssertEqual(SemanticVersion(symbolFive), SemanticVersion(major: 1, minor: 0, patch: 1)) } + + func testStringRepresentation() { + let oneComponent = SemanticVersion(major: 1, minor: 0, patch: 0) + + XCTAssertEqual(oneComponent.stringRepresentation(precisionUpToNonsignificant: .minor), "1.0") + XCTAssertEqual(oneComponent.stringRepresentation(precisionUpToNonsignificant: .patch), "1.0.0") + XCTAssertEqual(oneComponent.stringRepresentation(precisionUpToNonsignificant: .all), "1.0.0") + + let twoComponents = SemanticVersion(major: 1, minor: 2, patch: 0) + XCTAssertEqual(twoComponents.stringRepresentation(precisionUpToNonsignificant: .minor), "1.2") + XCTAssertEqual(twoComponents.stringRepresentation(precisionUpToNonsignificant: .patch), "1.2.0") + XCTAssertEqual(twoComponents.stringRepresentation(precisionUpToNonsignificant: .all), "1.2.0") + + let threeComponents = SemanticVersion(major: 1, minor: 2, patch: 3) + XCTAssertEqual(threeComponents.stringRepresentation(precisionUpToNonsignificant: .minor), "1.2.3") + XCTAssertEqual(threeComponents.stringRepresentation(precisionUpToNonsignificant: .patch), "1.2.3") + XCTAssertEqual(threeComponents.stringRepresentation(precisionUpToNonsignificant: .all), "1.2.3") + + let zeroVersion = SemanticVersion(major: 0, minor: 0, patch: 0) + XCTAssertEqual(zeroVersion.stringRepresentation(precisionUpToNonsignificant: .minor), "0.0") + XCTAssertEqual(zeroVersion.stringRepresentation(precisionUpToNonsignificant: .patch), "0.0.0") + XCTAssertEqual(zeroVersion.stringRepresentation(precisionUpToNonsignificant: .all), "0.0.0") + + let zeroMinorVersion = SemanticVersion(major: 1, minor: 0, patch: 1) + XCTAssertEqual(zeroMinorVersion.stringRepresentation(precisionUpToNonsignificant: .minor), "1.0.1") + XCTAssertEqual(zeroMinorVersion.stringRepresentation(precisionUpToNonsignificant: .patch), "1.0.1") + XCTAssertEqual(zeroMinorVersion.stringRepresentation(precisionUpToNonsignificant: .all), "1.0.1") + } + } diff --git a/Tests/SwiftDocCTests/Semantics/MetadataAvailabilityTests.swift b/Tests/SwiftDocCTests/Semantics/MetadataAvailabilityTests.swift index 7940148326..92329030da 100644 --- a/Tests/SwiftDocCTests/Semantics/MetadataAvailabilityTests.swift +++ b/Tests/SwiftDocCTests/Semantics/MetadataAvailabilityTests.swift @@ -86,7 +86,7 @@ class MetadataAvailabilityTests: XCTestCase { try assertDirective(Metadata.self, source: source) { directive, problems in let directive = try XCTUnwrap(directive) let platforms = directive.availability.map { $0.platform } - let introducedVersions = directive.availability.map { $0.introducedVersion } + let introducedVersions = directive.availability.map { $0.introduced } @@ -97,9 +97,9 @@ class MetadataAvailabilityTests: XCTestCase { .other("Package") ]) XCTAssertEqual(introducedVersions, [ - VersionTriplet(3, 5, 2), - VersionTriplet(3, 5, 0), - VersionTriplet(3, 0, 0) + SemanticVersion(major: 3, minor: 5, patch: 2), + SemanticVersion(major: 3, minor: 5, patch: 0), + SemanticVersion(major: 3, minor: 0, patch: 0) ]) XCTAssertEqual(0, problems.count)