Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix rare crash when tutorial file has same as documentation bundle identifier #517

Merged
merged 4 commits into from
Mar 29, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ final class PathHierarchyBasedLinkResolver {

/// Map the resolved identifiers to resolved topic references for a given bundle's article, tutorial, and technology root pages.
func addMappingForRoots(bundle: DocumentationBundle) {
resolvedReferenceMap[pathHierarchy.tutorialContainer.identifier] = bundle.tutorialsRootReference
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The root cause for this crash is that I had forgotten which is the "tutorial" page and which is the "technology" page so the tutorial link resolved the reference for the technology page and vice versa resulting in an assertion during rendering of the See Also section.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we rename these so that they are easier to distinguish?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's a good idea. There are still many places that use the "technology" terminology in the code and I think we should update them all to match the user-facing terminology.

I opened this issue about updating the general "technology" terminology in the code.

resolvedReferenceMap[pathHierarchy.tutorialContainer.identifier] = bundle.technologyTutorialsRootReference
resolvedReferenceMap[pathHierarchy.articlesContainer.identifier] = bundle.articlesDocumentationRootReference
resolvedReferenceMap[pathHierarchy.tutorialOverviewContainer.identifier] = bundle.technologyTutorialsRootReference
resolvedReferenceMap[pathHierarchy.tutorialOverviewContainer.identifier] = bundle.tutorialsRootReference
}

/// Map the resolved identifiers to resolved topic references for all symbols in the given symbol index.
Expand Down
46 changes: 42 additions & 4 deletions Tests/SwiftDocCTests/Rendering/AutomaticSeeAlsoTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@
import Foundation
import XCTest
@testable import SwiftDocC
import SwiftDocCTestUtilities

class AutomaticSeeAlsoTests: XCTestCase {

/// Test that a symbol with no authored See Also and with no curated siblings
/// does not have a See Also section.
func testNoSeeAlso() throws {
let (_, bundle, context) = try testBundleAndContext(copying: "TestBundle") { root in
/// Article that curates `SideClass`
/// Extension that curates `SideClass`
try """
# SideKit
# ``SideKit``
SideKit module root symbol
## Topics
### Basics
Expand All @@ -41,7 +42,7 @@ class AutomaticSeeAlsoTests: XCTestCase {
/// does include an authored See Also section
func testAuthoredSeeAlso() throws {
let (_, bundle, context) = try testBundleAndContext(copying: "TestBundle") { root in
/// Article that curates `SideClass`
/// Extension that curates `SideClass`
try """
# ``SideKit``
SideKit module root symbol
Expand Down Expand Up @@ -77,7 +78,7 @@ class AutomaticSeeAlsoTests: XCTestCase {
/// does include both in See Also with authored section first
func testAuthoredAndAutomaticSeeAlso() throws {
let (_, bundle, context) = try testBundleAndContext(copying: "TestBundle") { root in
/// Article that curates `SideClass`
/// Extension that curates `SideClass`
try """
# ``SideKit``
SideKit module root symbol
Expand Down Expand Up @@ -256,4 +257,41 @@ class AutomaticSeeAlsoTests: XCTestCase {
}
}

func testSeeAlsoWithSymbolAndTutorial() throws {
let exampleDocumentation = Folder(name: "MyKit.docc", content: [
CopyOfFile(original: Bundle.module.url(forResource: "mykit-one-symbol.symbols", withExtension: "json", subdirectory: "Test Resources")!),

// The tutorial has the same file name (excluding the file extension) as the module and as the bundle.
TextFile(name: "MyKit.tutorial", utf8Content: """
@Tutorials(name: "My Tutorials") {
@Intro(title: "My Intro") {
}
}
"""),

TextFile(name: "MyKit.md", utf8Content: """
# ``MyKit``

Curate a symbol and a tutorial together so that the symbol's generated See Also section includes the tutorial.

## Topics

- ``MyKit/MyClass/myFunction()``
- <doc:/tutorials/MyKit>
"""),
])
let tempURL = try createTemporaryDirectory()
let bundleURL = try exampleDocumentation.write(inside: tempURL)

let (_, bundle, context) = try loadBundle(from: bundleURL)

// Get a translated render node
let node = try context.entity(with: ResolvedTopicReference(bundleIdentifier: "MyKit", path: "/documentation/MyKit/MyClass/myFunction()", sourceLanguage: .swift))
var translator = RenderNodeTranslator(context: context, bundle: bundle, identifier: node.reference, source: nil)
let renderNode = translator.visit(node.semantic as! Symbol) as! RenderNode

// Verify there is a See Also with the resolved tutorial reference
XCTAssertEqual(renderNode.seeAlsoSections.count, 1)
XCTAssertEqual(renderNode.seeAlsoSections.first?.identifiers, ["doc://MyKit/tutorials/MyKit"])
}
}