Skip to content

Commit 353fc45

Browse files
Prevent the Render Node decoder from failing in the absence of the references key
* Fix single-article catalogs not rendering in Xcode DocC viewer rdar://111186939 * Fix failing index generation for single-article doccarchives (closes #711) * Added tests to validate correct generation of the index files for single-articles archives and the correct decoding of render nodes without the `references` key
1 parent 4fbad16 commit 353fc45

File tree

5 files changed

+111
-1
lines changed

5 files changed

+111
-1
lines changed

Sources/SwiftDocC/Model/Rendering/RenderNode/RenderNode+Codable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ extension RenderNode: Codable {
2222

2323
identifier = try container.decode(ResolvedTopicReference.self, forKey: .identifier)
2424
sections = try container.decode([CodableRenderSection].self, forKey: .sections).map { $0.section }
25-
references = try container.decode([String: CodableRenderReference].self, forKey: .references).mapValues({$0.reference})
25+
references = try (container.decodeIfPresent([String: CodableRenderReference].self, forKey: .references) ?? [:]).mapValues({$0.reference})
2626
metadata = try container.decode(RenderMetadata.self, forKey: .metadata)
2727
kind = try container.decode(Kind.self, forKey: .kind)
2828
hierarchy = try container.decodeIfPresent(RenderHierarchy.self, forKey: .hierarchy)

Tests/SwiftDocCTests/Converter/RenderNodeCodableTests.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ class RenderNodeCodableTests: XCTestCase {
4646
XCTAssertTrue(description.contains("schemaVersion"), "Missing key name in error description")
4747
}
4848
}
49+
func testMissingReferenceKey() throws {
50+
let renderNode = try! RenderNode.decode(fromJSON: missingReferenceKeyJSON)
51+
XCTAssertNotNil(renderNode)
52+
}
4953

5054
func testTypeMismatchError() {
5155
do {
@@ -244,3 +248,6 @@ fileprivate let emptyJSON = Data("{}".utf8)
244248
fileprivate let typeMismatch = Data("""
245249
{"schemaVersion":{"major":"type mismatch","minor":0,"patch":0}}
246250
""".utf8)
251+
fileprivate let missingReferenceKeyJSON = Data("""
252+
{"kind":"article","identifier":{"interfaceLanguage":"","url":"doc://org.swift.docc.example/documentation/Test-Bundle/article"},"abstract":[],"metadata":{},"schemaVersion":{"minor":3,"patch":0,"major":0},"sections":[],"hierarchy":{"paths":[[]]}}
253+
""".utf8)

Tests/SwiftDocCUtilitiesTests/IndexActionTests.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,37 @@ class IndexActionTests: XCTestCase {
6868
XCTAssertEqual(resultIndexDumps.count, 1)
6969
}
7070
#endif
71+
72+
func testIndexActionOutputContainsInterfaceLanguageContent() throws {
73+
// Convert a test bundle as input for the IndexAction
74+
let bundleURL = Bundle.module.url(
75+
forResource: "SingleArticleTestBundle", withExtension: "docc", subdirectory: "Test Bundles")!
76+
let targetURL = try createTemporaryDirectory()
77+
let templateURL = try createTemporaryDirectory().appendingPathComponent("template")
78+
try Folder.emptyHTMLTemplateDirectory.write(to: templateURL)
79+
let targetBundleURL = targetURL.appendingPathComponent("Result.builtdocs")
80+
var action = try ConvertAction(
81+
documentationBundleURL: bundleURL,
82+
outOfProcessResolver: nil,
83+
analyze: false,
84+
targetDirectory: targetBundleURL,
85+
htmlTemplateDirectory: templateURL,
86+
emitDigest: false,
87+
currentPlatforms: nil,
88+
temporaryDirectory: createTemporaryDirectory()
89+
)
90+
_ = try action.perform(logHandle: .standardOutput)
91+
let bundleIdentifier = "org.swift.docc.example"
92+
let indexURL = targetURL.appendingPathComponent("index")
93+
let engine = DiagnosticEngine(filterLevel: .warning)
94+
var indexAction = try IndexAction(
95+
documentationBundleURL: targetBundleURL,
96+
outputURL: indexURL,
97+
bundleIdentifier: bundleIdentifier,
98+
diagnosticEngine: engine
99+
)
100+
let indexPerform = try indexAction.perform(logHandle: .standardOutput)
101+
let index = try NavigatorIndex.readNavigatorIndex(url: indexPerform.outputs[0])
102+
XCTAssertEqual(index.availabilityIndex.interfaceLanguages.count, 1)
103+
}
71104
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>CFBundleName</key>
6+
<string>SingleArticleTestBundle</string>
7+
<key>CFBundleDisplayName</key>
8+
<string>SingleArticle Test Bundle</string>
9+
<key>CFBundleIdentifier</key>
10+
<string>org.swift.docc.example</string>
11+
<key>CFBundleIconFile</key>
12+
<string>DocumentationIcon</string>
13+
<key>CFBundleIconName</key>
14+
<string>DocumentationIcon</string>
15+
<key>CFBundlePackageType</key>
16+
<string>DOCS</string>
17+
<key>CFBundleSignature</key>
18+
<string>????</string>
19+
<key>CFBundleVersion</key>
20+
<string>0.1.0</string>
21+
<key>CDDefaultCodeListingLanguage</key>
22+
<string>swift</string>
23+
<key>CFBundleShortVersionString</key>
24+
<string>0.1.0</string>
25+
<key>CDAppleDefaultAvailability</key>
26+
<dict>
27+
<key>FillIntroduced</key>
28+
<array>
29+
<dict>
30+
<key>name</key>
31+
<string>macOS</string>
32+
<key>version</key>
33+
<string>10.9</string>
34+
</dict>
35+
<dict>
36+
<key>name</key>
37+
<string>iOS</string>
38+
<key>version</key>
39+
<string>11.1</string>
40+
</dict>
41+
<dict>
42+
<key>name</key>
43+
<string>tvOS</string>
44+
<key>version</key>
45+
<string>12.2</string>
46+
</dict>
47+
<dict>
48+
<key>name</key>
49+
<string>watchOS</string>
50+
<key>version</key>
51+
<string>13.3</string>
52+
</dict>
53+
</array>
54+
</dict>
55+
</dict>
56+
</plist>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Article
2+
3+
@Metadata {
4+
@TechnologyRoot
5+
}
6+
7+
This is an article.
8+
9+
## Overview
10+
11+
Overview
12+
13+
14+
<!-- Copyright (c) 2023 Apple Inc and the Swift Project authors. All Rights Reserved. -->

0 commit comments

Comments
 (0)