Skip to content

Commit

Permalink
Don't display beta tags for symbols with availability items without i…
Browse files Browse the repository at this point in the history
…ntroduced version. (swiftlang#1086)

Don't display beta tags for symbols with availability items without introduced version.

This change makes symbols without introduced versions but with deprecated versions to be
marked as `beta`.

Before this change a symbol with availability items without introduced versions were being marked as beta.

rdar://139245007
  • Loading branch information
sofiaromorales authored Nov 8, 2024
1 parent 5a690ce commit 864453f
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@ public class DocumentationContentRenderer {
}

/// Given a node, returns if it's a beta documentation symbol or not.
///
/// Symbols are only considered "in beta" if they are in beta for all platforms that they are available for.
func isBeta(_ node: DocumentationNode) -> Bool {
// We verify that this is a symbol with defined availability
// and that we're feeding in a current set of platforms to the context.
Expand All @@ -219,9 +221,14 @@ public class DocumentationContentRenderer {
// Verify that if current platforms are in beta, they match the introduced version of the symbol
for availability in symbolAvailability {
// If not available on this platform, skip to next platform.
guard !availability.isUnconditionallyUnavailable, let introduced = availability.introducedVersion else {
guard !availability.isUnconditionallyUnavailable else {
continue
}

// If the symbol doesn't have an introduced version for one of those platforms, we don't consider it "in beta".
guard let introduced = availability.introducedVersion else {
return false
}

// If we don't have introduced and current versions for the current platform
// we can't tell if the symbol is beta.
Expand Down
62 changes: 42 additions & 20 deletions Tests/SwiftDocCTests/Model/SemaToRenderNodeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1913,19 +1913,24 @@ Document
}

func testRendersBetaViolators() throws {
func makeTestBundle(currentPlatforms: [String : PlatformVersion]?, file: StaticString = #file, line: UInt = #line) throws -> (DocumentationBundle, DocumentationContext, ResolvedTopicReference) {
func makeTestBundle(currentPlatforms: [String : PlatformVersion]?, file: StaticString = #file, line: UInt = #line, referencePath: String) throws -> (DocumentationBundle, DocumentationContext, ResolvedTopicReference) {
var configuration = DocumentationContext.Configuration()
// Add missing platforms if their fallback platform is present.
var currentPlatforms = currentPlatforms ?? [:]
for (platform, fallbackPlatform) in DefaultAvailability.fallbackPlatforms where currentPlatforms[platform.displayName] == nil {
currentPlatforms[platform.displayName] = currentPlatforms[fallbackPlatform.displayName]
}
configuration.externalMetadata.currentPlatforms = currentPlatforms

let (_, bundle, context) = try testBundleAndContext(named: "TestBundle", configuration: configuration)

let reference = ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/documentation/MyKit/MyClass", sourceLanguage: .swift)
let reference = ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: referencePath, sourceLanguage: .swift)
return (bundle, context, reference)
}

// Not a beta platform
do {
let (bundle, context, reference) = try makeTestBundle(currentPlatforms: nil)
let (bundle, context, reference) = try makeTestBundle(currentPlatforms: nil, referencePath: "/documentation/MyKit/globalFunction(_:considering:)")

let node = try context.entity(with: reference)
let renderNode = try DocumentationNodeConverter(bundle: bundle, context: context).convert(node)
Expand All @@ -1940,7 +1945,7 @@ Document

let (bundle, context, reference) = try makeTestBundle(currentPlatforms: [
"Custom Name": PlatformVersion(VersionTriplet(100, 0, 0), beta: true)
])
], referencePath: "/documentation/MyKit/globalFunction(_:considering:)")
let node = try context.entity(with: reference)
(node.semantic as? Symbol)?.availability = SymbolGraph.Symbol.Availability(availability: [])
let documentationContentRendered = DocumentationContentRenderer(documentationContext: context, bundle: bundle)
Expand All @@ -1953,7 +1958,7 @@ Document
do {
let (bundle, context, reference) = try makeTestBundle(currentPlatforms: [
"tvOS": PlatformVersion(VersionTriplet(100, 0, 0), beta: true)
])
], referencePath: "/documentation/MyKit/globalFunction(_:considering:)")

let node = try context.entity(with: reference)
let renderNode = try DocumentationNodeConverter(bundle: bundle, context: context).convert(node)
Expand All @@ -1967,7 +1972,7 @@ Document
do {
let (bundle, context, reference) = try makeTestBundle(currentPlatforms: [
"macOS": PlatformVersion(VersionTriplet(100, 0, 0), beta: true)
])
], referencePath: "/documentation/MyKit/globalFunction(_:considering:)")

let node = try context.entity(with: reference)
let renderNode = try DocumentationNodeConverter(bundle: bundle, context: context).convert(node)
Expand All @@ -1981,21 +1986,21 @@ Document
do {
let (bundle, context, reference) = try makeTestBundle(currentPlatforms: [
"macOS": PlatformVersion(VersionTriplet(10, 15, 0), beta: true)
])
], referencePath: "/documentation/MyKit/globalFunction(_:considering:)")

let node = try context.entity(with: reference)
let renderNode = try DocumentationNodeConverter(bundle: bundle, context: context).convert(node)

// Verify platform beta was plumbed all the way to the render JSON
XCTAssertEqual(renderNode.metadata.platforms?.first(where: { $0.name == "macOS" })?.isBeta, true)
XCTAssertEqual(renderNode.metadata.platforms?.first(where: { $0.name == "macOS"})?.isBeta, true)
}

// Beta platform earlier than the introduced version

do {
let (bundle, context, reference) = try makeTestBundle(currentPlatforms: [
"macOS": PlatformVersion(VersionTriplet(10, 14, 0), beta: true)
])
], referencePath: "/documentation/MyKit/globalFunction(_:considering:)")

let node = try context.entity(with: reference)
let renderNode = try DocumentationNodeConverter(bundle: bundle, context: context).convert(node)
Expand All @@ -2004,36 +2009,36 @@ Document
XCTAssertEqual(renderNode.metadata.platforms?.first(where: { $0.name == "macOS" })?.isBeta, true)
}

// Set only some platforms to beta & the exact version MyClass is being introduced at
// Set only some platforms to beta & the exact version globalFunction is being introduced at

do {
let (bundle, context, reference) = try makeTestBundle(currentPlatforms: [
"macOS": PlatformVersion(VersionTriplet(10, 15, 0), beta: true),
"watchOS": PlatformVersion(VersionTriplet(9, 0, 0), beta: true),
"tvOS": PlatformVersion(VersionTriplet(1, 0, 0), beta: true),
])
], referencePath: "/documentation/MyKit/globalFunction(_:considering:)")

let node = try context.entity(with: reference)
let renderNode = try DocumentationNodeConverter(bundle: bundle, context: context).convert(node)

// Verify task group link is beta
XCTAssertEqual((renderNode.references["doc://org.swift.docc.example/documentation/MyKit/MyClass"] as? TopicRenderReference)?.isBeta, false)
// Verify task group link is not in beta betas "iOS" is not being marked as beta
XCTAssertEqual((renderNode.references["doc://org.swift.docc.example/documentation/MyKit/globalFunction(_:considering:)"] as? TopicRenderReference)?.isBeta, false)
}

// Set all platforms to beta & the exact version MyClass is being introduced at to test beta SDK documentation
// Set all platforms to beta & the exact version globalFunction is being introduced at to test beta SDK documentation
do {
let (bundle, context, reference) = try makeTestBundle(currentPlatforms: [
"macOS": PlatformVersion(VersionTriplet(10, 15, 0), beta: true),
"watchOS": PlatformVersion(VersionTriplet(6, 0, 0), beta: true),
"tvOS": PlatformVersion(VersionTriplet(13, 0, 0), beta: true),
"iOS": PlatformVersion(VersionTriplet(13, 0, 0), beta: true),
])
"iOS": PlatformVersion(VersionTriplet(13, 0, 0), beta: true)
], referencePath: "/documentation/MyKit/globalFunction(_:considering:)")

let node = try context.entity(with: reference)
let renderNode = try XCTUnwrap(DocumentationNodeConverter(bundle: bundle, context: context).convert(node))

// Verify task group link is beta
XCTAssertEqual((renderNode.references["doc://org.swift.docc.example/documentation/MyKit/MyClass"] as? TopicRenderReference)?.isBeta, true)
XCTAssertEqual((renderNode.references["doc://org.swift.docc.example/documentation/MyKit/globalFunction(_:considering:)"] as? TopicRenderReference)?.isBeta, true)
}

// Set all platforms to beta where the symbol is available,
Expand All @@ -2045,13 +2050,13 @@ Document
"iOS": PlatformVersion(VersionTriplet(13, 0, 0), beta: true),
"FictionalOS": PlatformVersion(VersionTriplet(42, 0, 0), beta: false),
"ImaginaryOS": PlatformVersion(VersionTriplet(3, 3, 3), beta: false),
])
], referencePath: "/documentation/MyKit/globalFunction(_:considering:)")

let node = try context.entity(with: reference)
let renderNode = try XCTUnwrap(DocumentationNodeConverter(bundle: bundle, context: context).convert(node))

// Verify task group link is beta
XCTAssertEqual((renderNode.references["doc://org.swift.docc.example/documentation/MyKit/MyClass"] as? TopicRenderReference)?.isBeta, true)
XCTAssertEqual((renderNode.references["doc://org.swift.docc.example/documentation/MyKit/globalFunction(_:considering:)"] as? TopicRenderReference)?.isBeta, true)

// Add ImaginaryOS platform - but make it unconditionally unavailable and
// verify that it doesn't affect the beta status
Expand All @@ -2064,7 +2069,24 @@ Document
let renderNode = try XCTUnwrap(DocumentationNodeConverter(bundle: bundle, context: context).convert(node))

// Verify task group link is beta
XCTAssertEqual((renderNode.references["doc://org.swift.docc.example/documentation/MyKit/MyClass"] as? TopicRenderReference)?.isBeta, true)
XCTAssertEqual((renderNode.references["doc://org.swift.docc.example/documentation/MyKit/globalFunction(_:considering:)"] as? TopicRenderReference)?.isBeta, true)
}

// Set all platforms to beta & the exact version MyClass is being introduced.
// Expect the symbol to no be in beta sinceit does not have an introduced version for iOS
do {
let (bundle, context, reference) = try makeTestBundle(currentPlatforms: [
"macOS": PlatformVersion(VersionTriplet(10, 15, 0), beta: true),
"watchOS": PlatformVersion(VersionTriplet(6, 0, 0), beta: true),
"tvOS": PlatformVersion(VersionTriplet(13, 0, 0), beta: true),
"iOS": PlatformVersion(VersionTriplet(13, 0, 0), beta: true)
], referencePath: "/documentation/MyKit")

let node = try context.entity(with: reference)
let renderNode = try XCTUnwrap(DocumentationNodeConverter(bundle: bundle, context: context).convert(node))

// Verify task group link is not in beta because `iOS` does not have an introduced version
XCTAssertEqual((renderNode.references["doc://org.swift.docc.example/documentation/MyKit/MyClass"] as? TopicRenderReference)?.isBeta, false)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,36 @@
],
"title" : "globalFunction(_:considering:)"
},
"availability" : [
{
"domain": "macOS",
"introduced": {
"major": 10,
"minor": 15
}
},
{
"domain": "watchOS",
"introduced": {
"major": 6,
"minor": 0
}
},
{
"domain": "tvOS",
"introduced": {
"major": 13,
"minor": 0
}
},
{
"domain": "iOS",
"introduced": {
"major": 13,
"minor": 0
}
}
],
"pathComponents" : [
"globalFunction(_:considering:)"
]
Expand Down

0 comments on commit 864453f

Please sign in to comment.