Skip to content

Commit ca63f54

Browse files
authored
Crawl the curation of auto-curated articles (#1236)
rdar://151731131
1 parent b44fe17 commit ca63f54

File tree

3 files changed

+90
-7
lines changed

3 files changed

+90
-7
lines changed

Sources/SwiftDocC/Infrastructure/DocumentationContext.swift

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2428,18 +2428,17 @@ public class DocumentationContext {
24282428

24292429
// Crawl the rest of the symbols that haven't been crawled so far in hierarchy pre-order.
24302430
allCuratedReferences = try crawlSymbolCuration(in: automaticallyCurated.map(\.symbol), bundle: bundle, initial: allCuratedReferences)
2431-
2432-
// Remove curation paths that have been created automatically above
2433-
// but we've found manual curation for in the second crawl pass.
2434-
removeUnneededAutomaticCuration(automaticallyCurated)
24352431

24362432
// Automatically curate articles that haven't been manually curated
24372433
// Article curation is only done automatically if there is only one root module
24382434
if let rootNode = rootNodeForAutomaticCuration {
24392435
let articleReferences = try autoCurateArticles(otherArticles, startingFrom: rootNode)
2440-
preResolveExternalLinks(references: articleReferences, localBundleID: bundle.id)
2441-
resolveLinks(curatedReferences: Set(articleReferences), bundle: bundle)
2436+
allCuratedReferences = try crawlSymbolCuration(in: articleReferences, bundle: bundle, initial: allCuratedReferences)
24422437
}
2438+
2439+
// Remove curation paths that have been created automatically above
2440+
// but we've found manual curation for in the second crawl pass.
2441+
removeUnneededAutomaticCuration(automaticallyCurated)
24432442

24442443
// Remove any empty "Extended Symbol" pages whose children have been curated elsewhere.
24452444
for module in rootModules {

Sources/SwiftDocC/Infrastructure/Topic Graph/TopicGraph.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ struct TopicGraph {
330330
}
331331

332332
var result = ""
333-
result.append("\(decorator) \(node[keyPath: keyPath])\r\n")
333+
result.append("\(decorator) \(node[keyPath: keyPath])\n")
334334
if let childEdges = edges[node.reference]?.sorted(by: { $0.path < $1.path }) {
335335
for (index, childRef) in childEdges.enumerated() {
336336
var decorator = decorator

Tests/SwiftDocCTests/Infrastructure/DocumentationCuratorTests.swift

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,90 @@ class DocumentationCuratorTests: XCTestCase {
201201
XCTAssertEqual(curationProblem.possibleSolutions.map(\.summary), ["Remove '- <doc:First>'"])
202202
}
203203

204+
func testCurationInUncuratedAPICollection() throws {
205+
// Everything should behave the same when an API Collection is automatically curated as when it is explicitly curated
206+
for shouldCurateAPICollection in [true, false] {
207+
let assertionMessageDescription = "when the API collection is \(shouldCurateAPICollection ? "explicitly curated" : "auto-curated as an article under the module")."
208+
209+
let catalog = Folder(name: "unit-test.docc", content: [
210+
JSONFile(name: "ModuleName.symbols.json", content: makeSymbolGraph(moduleName: "ModuleName", symbols: [
211+
makeSymbol(id: "some-symbol-id", kind: .class, pathComponents: ["SomeClass"])
212+
])),
213+
214+
TextFile(name: "ModuleName.md", utf8Content: """
215+
# ``ModuleName``
216+
217+
\(shouldCurateAPICollection ? "## Topics\n\n### Explicit curation\n\n- <doc:API-Collection>" : "")
218+
"""),
219+
220+
TextFile(name: "API-Collection.md", utf8Content: """
221+
# Some API collection
222+
223+
Curate the only symbol
224+
225+
## Topics
226+
227+
- ``SomeClass``
228+
- ``NotFound``
229+
"""),
230+
])
231+
let (bundle, context) = try loadBundle(catalog: catalog)
232+
XCTAssertEqual(
233+
context.problems.map(\.diagnostic.summary),
234+
[
235+
// There should only be a single problem about the unresolvable link in the API collection.
236+
"'NotFound' doesn't exist at '/unit-test/API-Collection'"
237+
],
238+
"Unexpected problems: \(context.problems.map(\.diagnostic.summary).joined(separator: "\n")) \(assertionMessageDescription)"
239+
)
240+
241+
// Verify that the topic graph paths to the symbol (although not used for its breadcrumbs) doesn't have the automatic edge anymore.
242+
let symbolReference = try XCTUnwrap(context.knownPages.first(where: { $0.lastPathComponent == "SomeClass" }))
243+
XCTAssertEqual(
244+
context.finitePaths(to: symbolReference).map { $0.map(\.path) },
245+
[
246+
// The automatic default `["/documentation/ModuleName"]` curation _shouldn't_ be here.
247+
248+
// The authored curation in the uncurated API collection
249+
["/documentation/ModuleName", "/documentation/unit-test/API-Collection"],
250+
],
251+
"Unexpected 'paths' to the symbol page \(assertionMessageDescription)"
252+
)
253+
254+
// Verify that the symbol page shouldn't auto-curate in its canonical location.
255+
let symbolTopicNode = try XCTUnwrap(context.topicGraph.nodeWithReference(symbolReference))
256+
XCTAssertFalse(symbolTopicNode.shouldAutoCurateInCanonicalLocation, "Symbol node is unexpectedly configured to auto-curate \(assertionMessageDescription)")
257+
258+
// Verify that the topic graph doesn't have the automatic edge anymore.
259+
XCTAssertEqual(context.dumpGraph(), """
260+
doc://unit-test/documentation/ModuleName
261+
╰ doc://unit-test/documentation/unit-test/API-Collection
262+
╰ doc://unit-test/documentation/ModuleName/SomeClass
263+
264+
""",
265+
"Unexpected topic graph \(assertionMessageDescription)"
266+
)
267+
268+
// Verify that the rendered top-level page doesn't have an automatic "Classes" topic section anymore.
269+
let converter = DocumentationNodeConverter(bundle: bundle, context: context)
270+
let moduleReference = try XCTUnwrap(context.soleRootModuleReference)
271+
let rootRenderNode = converter.convert(try context.entity(with: moduleReference))
272+
273+
XCTAssertEqual(
274+
rootRenderNode.topicSections.map(\.title),
275+
[shouldCurateAPICollection ? "Explicit curation" : "Articles"],
276+
"Unexpected rendered topic sections on the module page \(assertionMessageDescription)"
277+
)
278+
XCTAssertEqual(
279+
rootRenderNode.topicSections.map(\.identifiers),
280+
[
281+
["doc://unit-test/documentation/unit-test/API-Collection"],
282+
],
283+
"Unexpected rendered topic sections on the module page \(assertionMessageDescription)"
284+
)
285+
}
286+
}
287+
204288
func testModuleUnderTechnologyRoot() throws {
205289
let (_, bundle, context) = try testBundleAndContext(copying: "SourceLocations") { url in
206290
try """

0 commit comments

Comments
 (0)