1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
/*
This source file is part of the Swift.org open source project
Copyright (c) 2024 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception
See https://swift.org/LICENSE.txt for license information
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
import Foundation
import XCTest
@testable import SwiftDocC
import SwiftDocCTestUtilities
@testable import SymbolKit
class DoxygenTests: XCTestCase {
func testDoxygenDiscussionAndNote() throws {
let documentationLines: [SymbolGraph.LineList.Line] = """
This is an abstract.
@discussion This is a discussion linking to ``AnotherClass`` and ``AnotherClass/prop``.
@note This is a note linking to ``Class3`` and ``Class3/prop2``.
"""
.splitByNewlines
.enumerated()
.map { index, line in
SymbolGraph.LineList.Line(
text: line,
range: .init(start: .init(line: 1 + index, character: 1), end: .init(line: 1 + index, character: 1 + line.utf8.count))
)
}
let tempURL = try createTempFolder(content: [
Folder(name: "unit-test.docc", content: [
JSONFile(name: "ModuleName.symbols.json", content: makeSymbolGraph(
moduleName: "ModuleName",
symbols: [
SymbolGraph.Symbol(
identifier: .init(precise: "some-class-id", interfaceLanguage: SourceLanguage.swift.id),
names: .init(title: "SomeClass", navigator: nil, subHeading: nil, prose: nil),
pathComponents: ["SomeClass"],
docComment: .init(documentationLines),
accessLevel: .public,
kind: .init(parsedIdentifier: .class, displayName: "Kind Display Name"),
mixins: [:]
),
SymbolGraph.Symbol(
identifier: .init(precise: "another-class-id", interfaceLanguage: SourceLanguage.swift.id),
names: .init(title: "AnotherClass", navigator: nil, subHeading: nil, prose: nil),
pathComponents: ["AnotherClass"],
docComment: nil,
accessLevel: .public,
kind: .init(parsedIdentifier: .class, displayName: "Kind Display Name"),
mixins: [:]
),
SymbolGraph.Symbol(
identifier: .init(precise: "another-class-prop-id", interfaceLanguage: SourceLanguage.swift.id),
names: .init(title: "prop", navigator: nil, subHeading: nil, prose: nil),
pathComponents: ["AnotherClass", "prop"],
docComment: nil,
accessLevel: .public,
kind: .init(parsedIdentifier: .property, displayName: "Kind Display Name"),
mixins: [:]
),
SymbolGraph.Symbol(
identifier: .init(precise: "class3-id", interfaceLanguage: SourceLanguage.swift.id),
names: .init(title: "Class3", navigator: nil, subHeading: nil, prose: nil),
pathComponents: ["Class3"],
docComment: nil,
accessLevel: .public,
kind: .init(parsedIdentifier: .class, displayName: "Kind Display Name"),
mixins: [:]
),
SymbolGraph.Symbol(
identifier: .init(precise: "class3-prop-id", interfaceLanguage: SourceLanguage.swift.id),
names: .init(title: "prop", navigator: nil, subHeading: nil, prose: nil),
pathComponents: ["Class3", "prop"],
docComment: nil,
accessLevel: .public,
kind: .init(parsedIdentifier: .property, displayName: "Kind Display Name"),
mixins: [:]
),
]
)),
])
])
let (_, bundle, context) = try loadBundle(from: tempURL)
let reference = ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/documentation/ModuleName/SomeClass", sourceLanguage: .swift)
// Verify the expected content in the in-memory model
let node = try context.entity(with: reference)
let symbol = try XCTUnwrap(node.semantic as? Symbol)
XCTAssertEqual(symbol.abstract?.format(), "This is an abstract.")
XCTAssertEqual(symbol.discussion?.content.map { $0.format() }, [
#"\discussion This is a discussion linking to ``doc://unit-test/documentation/ModuleName/AnotherClass`` and ``doc://unit-test/documentation/ModuleName/AnotherClass/prop``."#,
#"\note This is a note linking to ``doc://unit-test/documentation/ModuleName/Class3`` and ``Class3/prop2``."#
])
// Verify the expected content in the render model
var translator = RenderNodeTranslator(context: context, bundle: bundle, identifier: node.reference, source: nil)
let renderNode = try XCTUnwrap(translator.visit(node.semantic) as? RenderNode)
XCTAssertEqual(renderNode.abstract, [.text("This is an abstract.")])
XCTAssertEqual(renderNode.primaryContentSections.count, 1)
let overviewSection = try XCTUnwrap(renderNode.primaryContentSections.first as? ContentRenderSection)
XCTAssertEqual(overviewSection.content.count, 3)
XCTAssertEqual(overviewSection.content, [
.heading(.init(level: 2, text: "Overview", anchor: "overview")),
.paragraph(.init(inlineContent: [
.text("This is a discussion linking to "),
.reference(
identifier: .init("doc://unit-test/documentation/ModuleName/AnotherClass"),
isActive: true,
overridingTitle: nil,
overridingTitleInlineContent: nil
),
.text(" and "),
.reference(
identifier: .init("doc://unit-test/documentation/ModuleName/AnotherClass/prop"),
isActive: true,
overridingTitle: nil,
overridingTitleInlineContent: nil
),
.text(".")
])),
.aside(.init(style: .init(asideKind: .note), content: [
.paragraph(.init(inlineContent: [
.text("This is a note linking to "),
.reference(
identifier: .init("doc://unit-test/documentation/ModuleName/Class3"),
isActive: true,
overridingTitle: nil,
overridingTitleInlineContent: nil
),
.text(" and "),
.codeVoice(code: "Class3/prop2"),
.text(".")
]))
])),
])
}
}
|