Skip to content

Commit af40518

Browse files
committed
Refactor render node output consumer test code
Refactor TestRenderNodeOutputConsumer into its own file so that it can be used in other tests.
1 parent b23e5a8 commit af40518

File tree

2 files changed

+121
-104
lines changed

2 files changed

+121
-104
lines changed

Tests/SwiftDocCTests/Model/SemaToRenderNodeMultiLanguageTests.swift

Lines changed: 10 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class SemaToRenderNodeMixedLanguageTests: XCTestCase {
7878
}
7979

8080
func assertOutputsMultiLanguageRenderNodes(variantInterfaceLanguage: String) throws {
81-
let outputConsumer = try mixedLanguageFrameworkConsumer { bundleURL in
81+
let outputConsumer = try renderNodeConsumer(for: "MixedLanguageFramework") { bundleURL in
8282
// Update the clang symbol graph with the Objective-C identifier given in variantInterfaceLanguage.
8383

8484
let clangSymbolGraphLocation = bundleURL
@@ -207,7 +207,7 @@ class SemaToRenderNodeMixedLanguageTests: XCTestCase {
207207
}
208208

209209
func testFrameworkRenderNodeHasExpectedContentAcrossLanguages() throws {
210-
let outputConsumer = try mixedLanguageFrameworkConsumer()
210+
let outputConsumer = try renderNodeConsumer(for: "MixedLanguageFramework")
211211
let mixedLanguageFrameworkRenderNode = try outputConsumer.renderNode(
212212
withIdentifier: "MixedLanguageFramework"
213213
)
@@ -322,7 +322,7 @@ class SemaToRenderNodeMixedLanguageTests: XCTestCase {
322322
}
323323

324324
func testObjectiveCAuthoredRenderNodeHasExpectedContentAcrossLanguages() throws {
325-
let outputConsumer = try mixedLanguageFrameworkConsumer()
325+
let outputConsumer = try renderNodeConsumer(for: "MixedLanguageFramework")
326326
let fooRenderNode = try outputConsumer.renderNode(withIdentifier: "c:@E@Foo")
327327

328328
assertExpectedContent(
@@ -476,7 +476,7 @@ class SemaToRenderNodeMixedLanguageTests: XCTestCase {
476476
}
477477

478478
func testArticleInMixedLanguageFramework() throws {
479-
let outputConsumer = try mixedLanguageFrameworkConsumer() { url in
479+
let outputConsumer = try renderNodeConsumer(for: "MixedLanguageFramework") { url in
480480
try """
481481
# MyArticle
482482
@@ -539,7 +539,7 @@ class SemaToRenderNodeMixedLanguageTests: XCTestCase {
539539
}
540540

541541
func testAPICollectionInMixedLanguageFramework() throws {
542-
let outputConsumer = try mixedLanguageFrameworkConsumer()
542+
let outputConsumer = try renderNodeConsumer(for: "MixedLanguageFramework")
543543

544544
let articleRenderNode = try outputConsumer.renderNode(withTitle: "APICollection")
545545

@@ -604,7 +604,7 @@ class SemaToRenderNodeMixedLanguageTests: XCTestCase {
604604
}
605605

606606
func testGeneratedImplementationsCollectionIsCuratedInAllAvailableLanguages() throws {
607-
let outputConsumer = try mixedLanguageFrameworkConsumer()
607+
let outputConsumer = try renderNodeConsumer(for: "MixedLanguageFramework")
608608

609609
let protocolRenderNode = try outputConsumer.renderNode(withTitle: "MixedLanguageClassConformingToProtocol")
610610

@@ -628,7 +628,7 @@ class SemaToRenderNodeMixedLanguageTests: XCTestCase {
628628
}
629629

630630
func testGeneratedImplementationsCollectionDoesNotCurateInAllUnavailableLanguages() throws {
631-
let outputConsumer = try mixedLanguageFrameworkConsumer { bundleURL in
631+
let outputConsumer = try renderNodeConsumer(for: "MixedLanguageFramework") { bundleURL in
632632
// Update the clang symbol graph to remove the protocol method requirement, so that it's effectively
633633
// available in Swift only.
634634

@@ -668,7 +668,7 @@ class SemaToRenderNodeMixedLanguageTests: XCTestCase {
668668
}
669669

670670
func testAutomaticSeeAlsoOnlyShowsAPIsAvailableInParentsLanguageForSymbol() throws {
671-
let outputConsumer = try mixedLanguageFrameworkConsumer()
671+
let outputConsumer = try renderNodeConsumer(for: "MixedLanguageFramework")
672672

673673
// Swift-only symbol.
674674
XCTAssertEqual(
@@ -738,8 +738,8 @@ class SemaToRenderNodeMixedLanguageTests: XCTestCase {
738738
}
739739

740740
func testMultiLanguageChildOfSingleParentSymbolIsCuratedInMultiLanguage() throws {
741-
let outputConsumer = try mixedLanguageFrameworkConsumer(
742-
bundleName: "MixedLanguageFrameworkSingleLanguageParent"
741+
let outputConsumer = try renderNodeConsumer(
742+
for: "MixedLanguageFrameworkSingleLanguageParent"
743743
)
744744

745745
let topLevelFrameworkPage = try outputConsumer.renderNode(withTitle: "MixedLanguageFramework")
@@ -891,97 +891,3 @@ class SemaToRenderNodeMixedLanguageTests: XCTestCase {
891891
)
892892
}
893893
}
894-
895-
private class TestRenderNodeOutputConsumer: ConvertOutputConsumer {
896-
var renderNodes = Synchronized<[RenderNode]>([])
897-
898-
func consume(renderNode: RenderNode) throws {
899-
renderNodes.sync { renderNodes in
900-
renderNodes.append(renderNode)
901-
}
902-
}
903-
904-
func consume(problems: [Problem]) throws { }
905-
func consume(assetsInBundle bundle: DocumentationBundle) throws { }
906-
func consume(linkableElementSummaries: [LinkDestinationSummary]) throws { }
907-
func consume(indexingRecords: [IndexingRecord]) throws { }
908-
func consume(assets: [RenderReferenceType: [RenderReference]]) throws { }
909-
func consume(benchmarks: Benchmark) throws { }
910-
func consume(documentationCoverageInfo: [CoverageDataEntry]) throws { }
911-
func consume(renderReferenceStore: RenderReferenceStore) throws { }
912-
func consume(buildMetadata: BuildMetadata) throws { }
913-
}
914-
915-
extension TestRenderNodeOutputConsumer {
916-
func renderNodes(withInterfaceLanguages interfaceLanguages: Set<String>?) -> [RenderNode] {
917-
renderNodes.sync { renderNodes in
918-
renderNodes.filter { renderNode in
919-
guard let interfaceLanguages = interfaceLanguages else {
920-
// If there are no interface languages set, return the nodes with no variants.
921-
return renderNode.variants == nil
922-
}
923-
924-
guard let variants = renderNode.variants else {
925-
return false
926-
}
927-
928-
let actualInterfaceLanguages: [String] = variants.flatMap { variant in
929-
variant.traits.compactMap { trait in
930-
guard case .interfaceLanguage(let interfaceLanguage) = trait else {
931-
return nil
932-
}
933-
return interfaceLanguage
934-
}
935-
}
936-
937-
return Set(actualInterfaceLanguages) == interfaceLanguages
938-
}
939-
}
940-
}
941-
942-
func renderNode(withIdentifier identifier: String) throws -> RenderNode {
943-
try renderNode(where: { renderNode in renderNode.metadata.externalID == identifier })
944-
}
945-
946-
func renderNode(withTitle title: String) throws -> RenderNode {
947-
try renderNode(where: { renderNode in renderNode.metadata.title == title })
948-
}
949-
950-
private func renderNode(where predicate: (RenderNode) -> Bool) throws -> RenderNode {
951-
let renderNode = renderNodes.sync { renderNodes in
952-
renderNodes.first { renderNode in
953-
predicate(renderNode)
954-
}
955-
}
956-
957-
return try XCTUnwrap(renderNode)
958-
}
959-
}
960-
961-
fileprivate extension SemaToRenderNodeMixedLanguageTests {
962-
func mixedLanguageFrameworkConsumer(
963-
bundleName: String = "MixedLanguageFramework",
964-
configureBundle: ((URL) throws -> Void)? = nil
965-
) throws -> TestRenderNodeOutputConsumer {
966-
let (bundleURL, _, context) = try testBundleAndContext(
967-
copying: bundleName,
968-
configureBundle: configureBundle
969-
)
970-
971-
var converter = DocumentationConverter(
972-
documentationBundleURL: bundleURL,
973-
emitDigest: false,
974-
documentationCoverageOptions: .noCoverage,
975-
currentPlatforms: nil,
976-
workspace: context.dataProvider as! DocumentationWorkspace,
977-
context: context,
978-
dataProvider: try LocalFileSystemDataProvider(rootURL: bundleURL),
979-
bundleDiscoveryOptions: BundleDiscoveryOptions()
980-
)
981-
982-
let outputConsumer = TestRenderNodeOutputConsumer()
983-
let (_, _) = try converter.convert(outputConsumer: outputConsumer)
984-
985-
return outputConsumer
986-
}
987-
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2022 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See https://swift.org/LICENSE.txt for license information
8+
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import Foundation
12+
@testable import SwiftDocC
13+
import XCTest
14+
15+
class TestRenderNodeOutputConsumer: ConvertOutputConsumer {
16+
var renderNodes = Synchronized<[RenderNode]>([])
17+
18+
func consume(renderNode: RenderNode) throws {
19+
renderNodes.sync { renderNodes in
20+
renderNodes.append(renderNode)
21+
}
22+
}
23+
24+
func consume(problems: [Problem]) throws { }
25+
func consume(assetsInBundle bundle: DocumentationBundle) throws { }
26+
func consume(linkableElementSummaries: [LinkDestinationSummary]) throws { }
27+
func consume(indexingRecords: [IndexingRecord]) throws { }
28+
func consume(assets: [RenderReferenceType: [RenderReference]]) throws { }
29+
func consume(benchmarks: Benchmark) throws { }
30+
func consume(documentationCoverageInfo: [CoverageDataEntry]) throws { }
31+
func consume(renderReferenceStore: RenderReferenceStore) throws { }
32+
func consume(buildMetadata: BuildMetadata) throws { }
33+
}
34+
35+
extension TestRenderNodeOutputConsumer {
36+
func allRenderNodes() -> [RenderNode] {
37+
renderNodes.sync { $0 }
38+
}
39+
40+
func renderNodes(withInterfaceLanguages interfaceLanguages: Set<String>?) -> [RenderNode] {
41+
renderNodes.sync { renderNodes in
42+
renderNodes.filter { renderNode in
43+
guard let interfaceLanguages = interfaceLanguages else {
44+
// If there are no interface languages set, return the nodes with no variants.
45+
return renderNode.variants == nil
46+
}
47+
48+
guard let variants = renderNode.variants else {
49+
return false
50+
}
51+
52+
let actualInterfaceLanguages: [String] = variants.flatMap { variant in
53+
variant.traits.compactMap { trait in
54+
guard case .interfaceLanguage(let interfaceLanguage) = trait else {
55+
return nil
56+
}
57+
return interfaceLanguage
58+
}
59+
}
60+
61+
return Set(actualInterfaceLanguages) == interfaceLanguages
62+
}
63+
}
64+
}
65+
66+
func renderNode(withIdentifier identifier: String) throws -> RenderNode {
67+
try renderNode(where: { renderNode in renderNode.metadata.externalID == identifier })
68+
}
69+
70+
func renderNode(withTitle title: String) throws -> RenderNode {
71+
try renderNode(where: { renderNode in renderNode.metadata.title == title })
72+
}
73+
74+
func renderNode(where predicate: (RenderNode) -> Bool) throws -> RenderNode {
75+
let renderNode = renderNodes.sync { renderNodes in
76+
renderNodes.first { renderNode in
77+
predicate(renderNode)
78+
}
79+
}
80+
81+
return try XCTUnwrap(renderNode)
82+
}
83+
}
84+
85+
extension XCTestCase {
86+
func renderNodeConsumer(
87+
for bundleName: String,
88+
configureBundle: ((URL) throws -> Void)? = nil
89+
) throws -> TestRenderNodeOutputConsumer {
90+
let (bundleURL, _, context) = try testBundleAndContext(
91+
copying: bundleName,
92+
configureBundle: configureBundle
93+
)
94+
95+
var converter = DocumentationConverter(
96+
documentationBundleURL: bundleURL,
97+
emitDigest: false,
98+
documentationCoverageOptions: .noCoverage,
99+
currentPlatforms: nil,
100+
workspace: context.dataProvider as! DocumentationWorkspace,
101+
context: context,
102+
dataProvider: try LocalFileSystemDataProvider(rootURL: bundleURL),
103+
bundleDiscoveryOptions: BundleDiscoveryOptions()
104+
)
105+
106+
let outputConsumer = TestRenderNodeOutputConsumer()
107+
let (_, _) = try converter.convert(outputConsumer: outputConsumer)
108+
109+
return outputConsumer
110+
}
111+
}

0 commit comments

Comments
 (0)