Skip to content

Commit 942c249

Browse files
authored
Keep external links to non-symbols in generated See Also sections (#788)
rdar://116540790
1 parent ed5f428 commit 942c249

File tree

2 files changed

+120
-6
lines changed

2 files changed

+120
-6
lines changed

Sources/SwiftDocC/Model/Rendering/DocumentationContentRenderer.swift

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -494,12 +494,7 @@ public class DocumentationContentRenderer {
494494

495495
// For external links, verify they've resolved successfully and return `nil` otherwise.
496496
if linkHost != reference.bundleIdentifier {
497-
let externalReference = ResolvedTopicReference(
498-
bundleIdentifier: linkHost,
499-
path: destination.path,
500-
sourceLanguages: node.availableSourceLanguages
501-
)
502-
if documentationContext.externallyResolvedSymbols.contains(externalReference) {
497+
if let url = ValidatedURL(destination), case .success(let externalReference) = documentationContext.externallyResolvedLinks[url] {
503498
return externalReference
504499
}
505500
return nil

Tests/SwiftDocCTests/Infrastructure/ExternalReferenceResolverTests.swift

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,4 +1069,123 @@ Document @1:1-1:35
10691069
XCTAssertEqual(deprecatedSection.first?.format().trimmingCharacters(in: .whitespaces), "Use <doc://com.external.testbundle/externally/resolved/path> instead.", "The link should have been resolved")
10701070
}
10711071
}
1072+
1073+
func testExternalLinkInGeneratedSeeAlso() throws {
1074+
let exampleDocumentation = Folder(name: "unit-test.docc", content: [
1075+
TextFile(name: "Root.md", utf8Content: """
1076+
# Root
1077+
1078+
@Metadata {
1079+
@TechnologyRoot
1080+
}
1081+
1082+
Curate two local articles and one external link
1083+
1084+
## Topics
1085+
1086+
- <doc:First>
1087+
- <doc://com.external.testbundle/something>
1088+
- <doc:Second>
1089+
"""),
1090+
1091+
TextFile(name: "First.md", utf8Content: """
1092+
# First
1093+
1094+
One article.
1095+
"""),
1096+
TextFile(name: "Second.md", utf8Content: """
1097+
# Second
1098+
1099+
Another article.
1100+
"""),
1101+
])
1102+
1103+
let resolver = TestExternalReferenceResolver()
1104+
1105+
let tempURL = try createTempFolder(content: [exampleDocumentation])
1106+
let (_, bundle, context) = try loadBundle(from: tempURL, externalResolvers: [resolver.bundleIdentifier: resolver])
1107+
1108+
XCTAssert(context.problems.isEmpty, "Unexpected problems: \(context.problems.map(\.diagnostic.summary))")
1109+
1110+
// Check the curation on the root page
1111+
let rootNode = try context.entity(with: XCTUnwrap(context.soleRootModuleReference))
1112+
let topics = try XCTUnwrap((rootNode.semantic as? Article)?.topics)
1113+
XCTAssertEqual(topics.taskGroups.count, 1, "The Root page should only have one task group because all the other pages are curated in one group so there are no automatic groups.")
1114+
let taskGroup = try XCTUnwrap(topics.taskGroups.first)
1115+
XCTAssertEqual(taskGroup.links.map(\.destination), [
1116+
"doc://unit-test/documentation/unit-test/First",
1117+
"doc://com.external.testbundle/externally/resolved/path",
1118+
"doc://unit-test/documentation/unit-test/Second",
1119+
])
1120+
1121+
// Check the rendered SeeAlso sections for the two curated articles.
1122+
let converter = DocumentationNodeConverter(bundle: bundle, context: context)
1123+
1124+
do {
1125+
let reference = ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/documentation/unit-test/First", sourceLanguage: .swift)
1126+
let node = try context.entity(with: reference)
1127+
let rendered = try converter.convert(node, at: nil)
1128+
1129+
XCTAssertEqual(rendered.seeAlsoSections.count, 1, "The page should only have the automatic See Also section created based on the curation on the Root page.")
1130+
let seeAlso = try XCTUnwrap(rendered.seeAlsoSections.first)
1131+
1132+
XCTAssertEqual(seeAlso.identifiers, [
1133+
"doc://com.external.testbundle/externally/resolved/path",
1134+
"doc://unit-test/documentation/unit-test/Second",
1135+
])
1136+
}
1137+
1138+
do {
1139+
let reference = ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/documentation/unit-test/Second", sourceLanguage: .swift)
1140+
let node = try context.entity(with: reference)
1141+
let rendered = try converter.convert(node, at: nil)
1142+
1143+
XCTAssertEqual(rendered.seeAlsoSections.count, 1, "The page should only have the automatic See Also section created based on the curation on the Root page.")
1144+
let seeAlso = try XCTUnwrap(rendered.seeAlsoSections.first)
1145+
1146+
XCTAssertEqual(seeAlso.identifiers, [
1147+
"doc://unit-test/documentation/unit-test/First",
1148+
"doc://com.external.testbundle/externally/resolved/path",
1149+
])
1150+
}
1151+
}
1152+
1153+
func testExternalLinkInAuthoredSeeAlso() throws {
1154+
let exampleDocumentation = Folder(name: "unit-test.docc", content: [
1155+
TextFile(name: "Root.md", utf8Content: """
1156+
# Root
1157+
1158+
@Metadata {
1159+
@TechnologyRoot
1160+
}
1161+
1162+
An external link in an authored SeeAlso section
1163+
1164+
## See Also
1165+
1166+
- <doc://com.external.testbundle/something>
1167+
"""),
1168+
])
1169+
1170+
let resolver = TestExternalReferenceResolver()
1171+
1172+
let tempURL = try createTempFolder(content: [exampleDocumentation])
1173+
let (_, bundle, context) = try loadBundle(from: tempURL, externalResolvers: [resolver.bundleIdentifier: resolver])
1174+
1175+
XCTAssert(context.problems.isEmpty, "Unexpected problems: \(context.problems.map(\.diagnostic.summary))")
1176+
1177+
1178+
// Check the curation on the root page
1179+
let reference = try XCTUnwrap(context.soleRootModuleReference)
1180+
let node = try context.entity(with: reference)
1181+
let converter = DocumentationNodeConverter(bundle: bundle, context: context)
1182+
let rendered = try converter.convert(node, at: nil)
1183+
1184+
XCTAssertEqual(rendered.seeAlsoSections.count, 1, "The page should only have the authored See Also section.")
1185+
let seeAlso = try XCTUnwrap(rendered.seeAlsoSections.first)
1186+
1187+
XCTAssertEqual(seeAlso.identifiers, [
1188+
"doc://com.external.testbundle/externally/resolved/path",
1189+
])
1190+
}
10721191
}

0 commit comments

Comments
 (0)