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
|
/*
This source file is part of the Swift.org open source project
Copyright (c) 2022 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
@testable import SwiftDocC
import XCTest
class TestRenderNodeOutputConsumer: ConvertOutputConsumer {
var renderNodes = Synchronized<[RenderNode]>([])
func consume(renderNode: RenderNode) throws {
renderNodes.sync { renderNodes in
renderNodes.append(renderNode)
}
}
func consume(problems: [Problem]) throws { }
func consume(assetsInBundle bundle: DocumentationBundle) throws { }
func consume(linkableElementSummaries: [LinkDestinationSummary]) throws { }
func consume(indexingRecords: [IndexingRecord]) throws { }
func consume(assets: [RenderReferenceType: [RenderReference]]) throws { }
func consume(benchmarks: Benchmark) throws { }
func consume(documentationCoverageInfo: [CoverageDataEntry]) throws { }
func consume(renderReferenceStore: RenderReferenceStore) throws { }
func consume(buildMetadata: BuildMetadata) throws { }
func consume(linkResolutionInformation: SerializableLinkResolutionInformation) throws { }
}
extension TestRenderNodeOutputConsumer {
func allRenderNodes() -> [RenderNode] {
renderNodes.sync { $0 }
}
func renderNodes(withInterfaceLanguages interfaceLanguages: Set<String>?) -> [RenderNode] {
renderNodes.sync { renderNodes in
renderNodes.filter { renderNode in
guard let interfaceLanguages else {
// If there are no interface languages set, return the nodes with no variants.
return renderNode.variants == nil
}
guard let variants = renderNode.variants else {
return false
}
let actualInterfaceLanguages: [String] = variants.flatMap { variant in
variant.traits.compactMap { trait in
guard case .interfaceLanguage(let interfaceLanguage) = trait else {
return nil
}
return interfaceLanguage
}
}
return Set(actualInterfaceLanguages) == interfaceLanguages
}
}
}
func renderNode(withIdentifier identifier: String) throws -> RenderNode {
try renderNode(where: { renderNode in renderNode.metadata.externalID == identifier })
}
func renderNode(withTitle title: String) throws -> RenderNode {
try renderNode(where: { renderNode in renderNode.metadata.title == title })
}
func renderNode(where predicate: (RenderNode) -> Bool) throws -> RenderNode {
let renderNode = renderNodes.sync { renderNodes in
renderNodes.first { renderNode in
predicate(renderNode)
}
}
return try XCTUnwrap(renderNode)
}
}
extension XCTestCase {
func renderNodeConsumer(
for bundleName: String,
configureBundle: ((URL) throws -> Void)? = nil,
configureConverter: ((inout DocumentationConverter) throws -> Void)? = nil
) throws -> TestRenderNodeOutputConsumer {
let (bundleURL, _, context) = try testBundleAndContext(
copying: bundleName,
configureBundle: configureBundle
)
var converter = DocumentationConverter(
documentationBundleURL: bundleURL,
emitDigest: false,
documentationCoverageOptions: .noCoverage,
currentPlatforms: nil,
workspace: context.dataProvider as! DocumentationWorkspace,
context: context,
dataProvider: try LocalFileSystemDataProvider(rootURL: bundleURL),
bundleDiscoveryOptions: BundleDiscoveryOptions()
)
try configureConverter?(&converter)
let outputConsumer = TestRenderNodeOutputConsumer()
let (_, _) = try converter.convert(outputConsumer: outputConsumer)
return outputConsumer
}
}
|