diff --git a/Sources/SwiftDocC/Indexing/RenderBlockContent+TextIndexing.swift b/Sources/SwiftDocC/Indexing/RenderBlockContent+TextIndexing.swift index c99bdd3847..9bd7c8e1f1 100644 --- a/Sources/SwiftDocC/Indexing/RenderBlockContent+TextIndexing.swift +++ b/Sources/SwiftDocC/Indexing/RenderBlockContent+TextIndexing.swift @@ -11,8 +11,8 @@ extension RenderBlockContent: TextIndexing { public var headings: [String] { switch self { - case .heading(_, let text, _): - return [text] + case .heading(let h): + return [h.text] default: return [] } @@ -20,44 +20,46 @@ extension RenderBlockContent: TextIndexing { public func rawIndexableTextContent(references: [String : RenderReference]) -> String { switch self { - case let .aside(_, blocks): - return blocks.rawIndexableTextContent(references: references) - case let .orderedList(items): - return items.map { + case let .aside(a): + return a.content.rawIndexableTextContent(references: references) + case let .orderedList(l): + return l.items.map { $0.content.rawIndexableTextContent(references: references) }.joined(separator: " ") - case let .paragraph(blocks): - return blocks.rawIndexableTextContent(references: references) - case let .step(blocks, caption, _, _, _): - return (blocks + caption).rawIndexableTextContent(references: references) - case let .unorderedList(items): - return items.map { + case let .paragraph(p): + return p.inlineContent.rawIndexableTextContent(references: references) + case let .step(s): + return (s.content + s.caption).rawIndexableTextContent(references: references) + case let .unorderedList(l): + return l.items.map { $0.content.rawIndexableTextContent(references: references) }.joined(separator: " ") - case .codeListing(_, _, let metadata): - return metadata?.rawIndexableTextContent(references: references) ?? "" - case let .heading(_, text, _): - return text + case let .codeListing(l): + return l.metadata?.rawIndexableTextContent(references: references) ?? "" + case let .heading(h): + return h.text case .endpointExample: return "" - case .dictionaryExample(summary: let summary, example: _): - return summary?.rawIndexableTextContent(references: references) ?? "" - case .table(_, let rows, let metadata): - let content = rows.map { + case .dictionaryExample(let e): + return e.summary?.rawIndexableTextContent(references: references) ?? "" + case .table(let t): + let content = t.rows.map { return $0.cells.map { return $0.rawIndexableTextContent(references: references) }.joined(separator: " ") }.joined(separator: " ") - let meta = metadata?.rawIndexableTextContent(references: references) ?? "" + let meta = t.metadata?.rawIndexableTextContent(references: references) ?? "" return content + " " + meta - case .termList(let items): - return items.map { + case .termList(let l): + return l.items.map { let definition = $0.definition.content.rawIndexableTextContent(references: references) return $0.term.inlineContent.rawIndexableTextContent(references: references) + ( definition.isEmpty ? "" : " \(definition)" ) }.joined(separator: " ") + default: + fatalError("unknown RenderBlockContent case in rawIndexableTextContent") } } } diff --git a/Sources/SwiftDocC/Indexing/RenderNode+Indexable.swift b/Sources/SwiftDocC/Indexing/RenderNode+Indexable.swift index dee709feb3..fcc4dc0358 100644 --- a/Sources/SwiftDocC/Indexing/RenderNode+Indexable.swift +++ b/Sources/SwiftDocC/Indexing/RenderNode+Indexable.swift @@ -28,7 +28,7 @@ extension RenderNode { return sections } - return [ContentRenderSection(kind: .content, content: [.paragraph(inlineContent: abstract ?? [])])] + return [ContentRenderSection(kind: .content, content: [.paragraph(.init(inlineContent: abstract ?? []))])] + primaryContentSections } } @@ -56,7 +56,7 @@ extension RenderNode: Indexable { let summaryParagraph: RenderBlockContent? if let abstract = self.abstract { - summaryParagraph = RenderBlockContent.paragraph(inlineContent: abstract) + summaryParagraph = RenderBlockContent.paragraph(.init(inlineContent: abstract)) } else if let intro = self.sections.first as? IntroRenderSection, let firstBlock = intro.content.first, case .paragraph = firstBlock { summaryParagraph = firstBlock } else { diff --git a/Sources/SwiftDocC/LinkTargets/LinkDestinationSummary.swift b/Sources/SwiftDocC/LinkTargets/LinkDestinationSummary.swift index b107c988df..323f17a2cf 100644 --- a/Sources/SwiftDocC/LinkTargets/LinkDestinationSummary.swift +++ b/Sources/SwiftDocC/LinkTargets/LinkDestinationSummary.swift @@ -256,10 +256,10 @@ extension Abstracted { /// - Parameter compiler: The content compiler to render the abstract. /// - Returns: The rendered abstract, or `nil` of the element doesn't have an abstract. func renderedAbstract(using compiler: inout RenderContentCompiler) -> LinkDestinationSummary.Abstract? { - guard let abstract = abstract, case RenderBlockContent.paragraph(let inlineContent)? = compiler.visitParagraph(abstract).first else { + guard let abstract = abstract, case RenderBlockContent.paragraph(let p)? = compiler.visitParagraph(abstract).first else { return nil } - return inlineContent + return p.inlineContent } } @@ -303,10 +303,10 @@ extension LinkDestinationSummary { let title = symbol.titleVariants[summaryTrait] ?? symbol.title func renderSymbolAbstract(_ symbolAbstract: Paragraph?) -> Abstract? { - guard let abstractParagraph = symbolAbstract, case RenderBlockContent.paragraph(let inlineContent)? = compiler.visitParagraph(abstractParagraph).first else { + guard let abstractParagraph = symbolAbstract, case RenderBlockContent.paragraph(let p)? = compiler.visitParagraph(abstractParagraph).first else { return nil } - return inlineContent + return p.inlineContent } let abstract = renderSymbolAbstract(symbol.abstractVariants[summaryTrait] ?? symbol.abstract) @@ -387,8 +387,8 @@ extension LinkDestinationSummary { let abstract: Abstract? if let abstracted = landmark as? Abstracted { abstract = abstracted.renderedAbstract(using: &compiler) ?? [] - } else if let paragraph = landmark.markup.children.lazy.compactMap({ $0 as? Paragraph }).first, case RenderBlockContent.paragraph(let inlineContent)? = compiler.visitParagraph(paragraph).first { - abstract = inlineContent + } else if let paragraph = landmark.markup.children.lazy.compactMap({ $0 as? Paragraph }).first, case RenderBlockContent.paragraph(let p)? = compiler.visitParagraph(paragraph).first { + abstract = p.inlineContent } else { abstract = nil } diff --git a/Sources/SwiftDocC/Model/Rendering/Content/Extensions/RenderTermLists.swift b/Sources/SwiftDocC/Model/Rendering/Content/Extensions/RenderTermLists.swift index 56afdf8780..e2fb0dd0ae 100644 --- a/Sources/SwiftDocC/Model/Rendering/Content/Extensions/RenderTermLists.swift +++ b/Sources/SwiftDocC/Model/Rendering/Content/Extensions/RenderTermLists.swift @@ -73,9 +73,9 @@ extension Collection where Element == RenderBlockContent.ListItem { /// list items. private func listWithItems(_ items: [ListableItem]) -> RenderContent { if let unorderedListItems = items as? [RenderBlockContent.ListItem] { - return RenderBlockContent.unorderedList(items: unorderedListItems) + return RenderBlockContent.unorderedList(.init(items: unorderedListItems)) } else if let termListItems = items as? [RenderBlockContent.TermListItem] { - return RenderBlockContent.termList(items: termListItems) + return RenderBlockContent.termList(.init(items: termListItems)) } else { fatalError() } @@ -89,7 +89,7 @@ extension RenderBlockContent.TermListItem { /// given list item is not deemed to be a term list item, this /// returns `nil`. init?(_ listItem: RenderBlockContent.ListItem) { - guard case let .paragraph(firstParagraphInlines) = listItem.content.first else { + guard case let .paragraph(firstParagraph) = listItem.content.first else { // The first child of the list item wasn't a paragraph, so // don't continue checking to see if this is a term list item. return nil @@ -98,7 +98,7 @@ extension RenderBlockContent.TermListItem { // Collapse any contiguous text elements before checking // for term indication - let collapsedFirstParagraphInlines = firstParagraphInlines.collapsingContiguousTextElements() + let collapsedFirstParagraphInlines = firstParagraph.inlineContent.collapsingContiguousTextElements() let termDefinitionSeparator = ":" guard let (termInlines, firstDefinitionInlines) = collapsedFirstParagraphInlines.separatedForTermDefinition(separator: termDefinitionSeparator) else { @@ -112,8 +112,8 @@ extension RenderBlockContent.TermListItem { // Use the definition contents from the first paragraph along // with the subsequent block elements in this list item as the // complete definition. - let definition = RenderBlockContent.TermListItem.Definition(content: [RenderBlockContent.paragraph(inlineContent: firstDefinitionInlines)] + subsequentBlockContents) - + let definition = RenderBlockContent.TermListItem.Definition(content: [RenderBlockContent.paragraph(.init(inlineContent: firstDefinitionInlines))] + subsequentBlockContents) + self = RenderBlockContent.TermListItem(term: term, definition: definition) } } diff --git a/Sources/SwiftDocC/Model/Rendering/Content/RenderBlockContent.swift b/Sources/SwiftDocC/Model/Rendering/Content/RenderBlockContent.swift index bcc38d6a05..9ee29f427d 100644 --- a/Sources/SwiftDocC/Model/Rendering/Content/RenderBlockContent.swift +++ b/Sources/SwiftDocC/Model/Rendering/Content/RenderBlockContent.swift @@ -37,29 +37,208 @@ import Markdown /// Block elements can be nested, for example, an aside note contains one or more paragraphs of text. public enum RenderBlockContent: Equatable { /// A paragraph of content. - case paragraph(inlineContent: [RenderInlineContent]) + case paragraph(Paragraph) /// An aside block. - case aside(style: AsideStyle, content: [RenderBlockContent]) + case aside(Aside) /// A block of sample code. - case codeListing(syntax: String?, code: [String], metadata: RenderContentMetadata?) + case codeListing(CodeListing) /// A heading with the given level. - case heading(level: Int, text: String, anchor: String?) + case heading(Heading) /// A list that contains ordered items. - case orderedList(items: [ListItem]) + case orderedList(OrderedList) /// A list that contains unordered items. - case unorderedList(items: [ListItem]) + case unorderedList(UnorderedList) /// A step in a multi-step tutorial. - case step(content: [RenderBlockContent], caption: [RenderBlockContent], media: RenderReferenceIdentifier?, code: RenderReferenceIdentifier?, runtimePreview: RenderReferenceIdentifier?) + case step(TutorialStep) /// A REST endpoint example that includes a request and the expected response. - case endpointExample(summary: [RenderBlockContent]?, request: CodeExample, response: CodeExample) + case endpointExample(EndpointExample) /// An example that contains a sample code block. - case dictionaryExample(summary: [RenderBlockContent]?, example: CodeExample) + case dictionaryExample(DictionaryExample) /// A list of terms. - case termList(items: [TermListItem]) + case termList(TermList) /// A table that contains a list of row data. - case table(header: HeaderType, rows: [TableRow], metadata: RenderContentMetadata?) + case table(Table) + + // Warning: If you add a new case to this enum, make sure to handle it in the Codable + // conformance at the bottom of this file, and in the `rawIndexableTextContent` method in + // RenderBlockContent+TextIndexing.swift! + + // This empty-marker case is here because non-frozen enums are only available when Library + // Evolution is enabled, which is not available to Swift Packages without unsafe flags + // (rdar://78773361). This can be removed once that is available and applied to Swift-DocC + // (rdar://89033233). + @available(*, deprecated, message: "this enum is nonfrozen and may be expanded in the future; please add a `default` case instead of matching this one") + case _nonfrozenEnum_useDefaultCase + + /// A paragraph of content. + public struct Paragraph: Equatable { + /// The content inside the paragraph. + public var inlineContent: [RenderInlineContent] + + /// Creates a new paragraph with the given content. + public init(inlineContent: [RenderInlineContent]) { + self.inlineContent = inlineContent + } + } + + /// An aside block. + public struct Aside: Equatable { + /// The style of this aside block. + public var style: AsideStyle + + /// The content inside this aside block. + public var content: [RenderBlockContent] + + public init(style: AsideStyle, content: [RenderBlockContent]) { + self.style = style + self.content = content + } + } + + /// A block of sample code. + public struct CodeListing: Equatable { + /// The language to use for syntax highlighting, if given. + public var syntax: String? + /// The lines of code inside the code block. + public var code: [String] + /// Additional metadata for this code block. + public var metadata: RenderContentMetadata? + + /// Make a new `CodeListing` with the given data. + public init(syntax: String?, code: [String], metadata: RenderContentMetadata?) { + self.syntax = syntax + self.code = code + self.metadata = metadata + } + } + + /// A heading with the given level. + public struct Heading: Equatable { + /// The level of the heading. + /// + /// This correlates with heading levels in HTML, so a level of 1 is given the most + /// prominence, and a level of 6 the least prominence. + public var level: Int + + /// The text in the heading. + public var text: String + + /// An optional anchor slug that can be used to link to the heading. + public var anchor: String? + + /// Creates a new heading with the given data. + public init(level: Int, text: String, anchor: String?) { + self.level = level + self.text = text + self.anchor = anchor + } + } + + /// A list that contains ordered items. + public struct OrderedList: Equatable { + /// The items in this list. + public var items: [ListItem] + + /// Creates a new ordered list with the given items. + public init(items: [ListItem]) { + self.items = items + } + } + + /// A list that contains unordered items. + public struct UnorderedList: Equatable { + /// The items in this list. + public var items: [ListItem] + + /// Creates a new unordered list with the given items. + public init(items: [ListItem]) { + self.items = items + } + } + + /// A step in a multi-step tutorial. + public struct TutorialStep: Equatable { + /// The content inside this tutorial step. + public var content: [RenderBlockContent] + /// The caption for the step. + public var caption: [RenderBlockContent] + /// An optional media reference to accompany the step. + public var media: RenderReferenceIdentifier? + /// The source code file associated with this step. + public var code: RenderReferenceIdentifier? + /// A rendering of the tutorial step, if available. + public var runtimePreview: RenderReferenceIdentifier? + + /// Creates a new tutorial step with the given items. + public init(content: [RenderBlockContent], caption: [RenderBlockContent], media: RenderReferenceIdentifier? = nil, code: RenderReferenceIdentifier? = nil, runtimePreview: RenderReferenceIdentifier? = nil) { + self.content = content + self.caption = caption + self.media = media + self.code = code + self.runtimePreview = runtimePreview + } + } + + /// A REST endpoint example that includes a request and the expected response. + public struct EndpointExample: Equatable { + /// A summary of the example. + public var summary: [RenderBlockContent]? + /// The request portion of the example. + public var request: CodeExample + /// The expected response for the given request. + public var response: CodeExample + + /// Creates a new REST endpoint example with the given data. + public init(summary: [RenderBlockContent]? = nil, request: CodeExample, response: CodeExample) { + self.summary = summary + self.request = request + self.response = response + } + } + + /// An example that contains a sample code block. + public struct DictionaryExample: Equatable { + /// A summary of the sample code block. + public var summary: [RenderBlockContent]? + /// The sample code for the example. + public var example: CodeExample + + /// Creates a new example with the given data. + public init(summary: [RenderBlockContent]? = nil, example: CodeExample) { + self.summary = summary + self.example = example + } + } + + /// A list of terms. + public struct TermList: Equatable { + /// The items in this list. + public var items: [TermListItem] + + /// Creates a new term list with the given items. + public init(items: [TermListItem]) { + self.items = items + } + } + + /// A table that contains a list of row data. + public struct Table: Equatable { + /// The style of header in this table. + public var header: HeaderType + /// The rows in this table. + public var rows: [TableRow] + /// Additional metadata for this table, if present. + public var metadata: RenderContentMetadata? + + /// Creates a new table with the given data. + public init(header: HeaderType, rows: [TableRow], metadata: RenderContentMetadata? = nil) { + self.header = header + self.rows = rows + self.metadata = metadata + } + } /// An item in a list. public struct ListItem: Codable, Equatable { @@ -129,7 +308,7 @@ public enum RenderBlockContent: Equatable { /// Creates an aside type for the specified aside kind. /// - Parameter asideKind: The aside kind that provides the display name. - public init(asideKind: Aside.Kind) { + public init(asideKind: Markdown.Aside.Kind) { self.rawValue = asideKind.rawValue } @@ -241,43 +420,43 @@ extension RenderBlockContent: Codable { switch type { case .paragraph: - self = try .paragraph(inlineContent: container.decode([RenderInlineContent].self, forKey: .inlineContent)) + self = try .paragraph(.init(inlineContent: container.decode([RenderInlineContent].self, forKey: .inlineContent))) case .aside: var style = try container.decode(AsideStyle.self, forKey: .style) if style.renderKind == "note", let displayName = try container.decodeIfPresent(String.self, forKey: .name) { style = AsideStyle(displayName: displayName) } - self = try .aside(style: style, content: container.decode([RenderBlockContent].self, forKey: .content)) + self = try .aside(.init(style: style, content: container.decode([RenderBlockContent].self, forKey: .content))) case .codeListing: - self = try .codeListing( + self = try .codeListing(.init( syntax: container.decodeIfPresent(String.self, forKey: .syntax), code: container.decode([String].self, forKey: .code), metadata: container.decodeIfPresent(RenderContentMetadata.self, forKey: .metadata) - ) + )) case .heading: - self = try .heading(level: container.decode(Int.self, forKey: .level), text: container.decode(String.self, forKey: .text), anchor: container.decodeIfPresent(String.self, forKey: .anchor)) + self = try .heading(.init(level: container.decode(Int.self, forKey: .level), text: container.decode(String.self, forKey: .text), anchor: container.decodeIfPresent(String.self, forKey: .anchor))) case .orderedList: - self = try .orderedList(items: container.decode([ListItem].self, forKey: .items)) + self = try .orderedList(.init(items: container.decode([ListItem].self, forKey: .items))) case .unorderedList: - self = try .unorderedList(items: container.decode([ListItem].self, forKey: .items)) + self = try .unorderedList(.init(items: container.decode([ListItem].self, forKey: .items))) case .step: - self = try .step(content: container.decode([RenderBlockContent].self, forKey: .content), caption: container.decodeIfPresent([RenderBlockContent].self, forKey: .caption) ?? [], media: container.decode(RenderReferenceIdentifier?.self, forKey: .media), code: container.decode(RenderReferenceIdentifier?.self, forKey: .code), runtimePreview: container.decode(RenderReferenceIdentifier?.self, forKey: .runtimePreview)) + self = try .step(.init(content: container.decode([RenderBlockContent].self, forKey: .content), caption: container.decodeIfPresent([RenderBlockContent].self, forKey: .caption) ?? [], media: container.decode(RenderReferenceIdentifier?.self, forKey: .media), code: container.decode(RenderReferenceIdentifier?.self, forKey: .code), runtimePreview: container.decode(RenderReferenceIdentifier?.self, forKey: .runtimePreview))) case .endpointExample: - self = try .endpointExample( + self = try .endpointExample(.init( summary: container.decodeIfPresent([RenderBlockContent].self, forKey: .summary), request: container.decode(CodeExample.self, forKey: .request), response: container.decode(CodeExample.self, forKey: .response) - ) + )) case .dictionaryExample: - self = try .dictionaryExample(summary: container.decodeIfPresent([RenderBlockContent].self, forKey: .summary), example: container.decode(CodeExample.self, forKey: .example)) + self = try .dictionaryExample(.init(summary: container.decodeIfPresent([RenderBlockContent].self, forKey: .summary), example: container.decode(CodeExample.self, forKey: .example))) case .table: - self = try .table( + self = try .table(.init( header: container.decode(HeaderType.self, forKey: .header), rows: container.decode([TableRow].self, forKey: .rows), metadata: container.decodeIfPresent(RenderContentMetadata.self, forKey: .metadata) - ) + )) case .termList: - self = try .termList(items: container.decode([TermListItem].self, forKey: .items)) + self = try .termList(.init(items: container.decode([TermListItem].self, forKey: .items))) } } @@ -298,6 +477,7 @@ extension RenderBlockContent: Codable { case .dictionaryExample: return .dictionaryExample case .table: return .table case .termList: return .termList + default: fatalError("unknown RenderBlockContent case in type property") } } @@ -306,43 +486,45 @@ extension RenderBlockContent: Codable { try container.encode(type, forKey: .type) switch self { - case .paragraph(let inlineContent): - try container.encode(inlineContent, forKey: .inlineContent) - case .aside(let style, let content): - try container.encode(style.renderKind, forKey: .style) - try container.encode(style.displayName, forKey: .name) - try container.encode(content, forKey: .content) - case .codeListing(let syntax, let code, metadata: let metadata): - try container.encode(syntax, forKey: .syntax) - try container.encode(code, forKey: .code) - try container.encodeIfPresent(metadata, forKey: .metadata) - case .heading(let level, let text, let anchor): - try container.encode(level, forKey: .level) - try container.encode(text, forKey: .text) - try container.encode(anchor, forKey: .anchor) - case .orderedList(let items): - try container.encode(items, forKey: .items) - case .unorderedList(let items): - try container.encode(items, forKey: .items) - case .step(let content, let caption, let media, let code, let runtimePreview): - try container.encode(content, forKey: .content) - try container.encode(caption, forKey: .caption) - try container.encode(media, forKey: .media) - try container.encode(code, forKey: .code) - try container.encode(runtimePreview, forKey: .runtimePreview) - case .endpointExample(summary: let summary, request: let request, response: let response): - try container.encodeIfPresent(summary, forKey: .summary) - try container.encode(request, forKey: .request) - try container.encode(response, forKey: .response) - case .dictionaryExample(summary: let summary, example: let example): - try container.encodeIfPresent(summary, forKey: .summary) - try container.encode(example, forKey: .example) - case .table(header: let header, rows: let rows, metadata: let metadata): - try container.encode(header, forKey: .header) - try container.encode(rows, forKey: .rows) - try container.encodeIfPresent(metadata, forKey: .metadata) - case .termList(items: let items): - try container.encode(items, forKey: .items) + case .paragraph(let p): + try container.encode(p.inlineContent, forKey: .inlineContent) + case .aside(let a): + try container.encode(a.style.renderKind, forKey: .style) + try container.encode(a.style.displayName, forKey: .name) + try container.encode(a.content, forKey: .content) + case .codeListing(let l): + try container.encode(l.syntax, forKey: .syntax) + try container.encode(l.code, forKey: .code) + try container.encodeIfPresent(l.metadata, forKey: .metadata) + case .heading(let h): + try container.encode(h.level, forKey: .level) + try container.encode(h.text, forKey: .text) + try container.encode(h.anchor, forKey: .anchor) + case .orderedList(let l): + try container.encode(l.items, forKey: .items) + case .unorderedList(let l): + try container.encode(l.items, forKey: .items) + case .step(let s): + try container.encode(s.content, forKey: .content) + try container.encode(s.caption, forKey: .caption) + try container.encode(s.media, forKey: .media) + try container.encode(s.code, forKey: .code) + try container.encode(s.runtimePreview, forKey: .runtimePreview) + case .endpointExample(let e): + try container.encodeIfPresent(e.summary, forKey: .summary) + try container.encode(e.request, forKey: .request) + try container.encode(e.response, forKey: .response) + case .dictionaryExample(let e): + try container.encodeIfPresent(e.summary, forKey: .summary) + try container.encode(e.example, forKey: .example) + case .table(let t): + try container.encode(t.header, forKey: .header) + try container.encode(t.rows, forKey: .rows) + try container.encodeIfPresent(t.metadata, forKey: .metadata) + case .termList(items: let l): + try container.encode(l.items, forKey: .items) + default: + fatalError("unknown RenderBlockContent case in encode method") } } } diff --git a/Sources/SwiftDocC/Model/Rendering/DocumentationContentRenderer.swift b/Sources/SwiftDocC/Model/Rendering/DocumentationContentRenderer.swift index 7f660b61d1..c51af878de 100644 --- a/Sources/SwiftDocC/Model/Rendering/DocumentationContentRenderer.swift +++ b/Sources/SwiftDocC/Model/Rendering/DocumentationContentRenderer.swift @@ -327,9 +327,9 @@ public class DocumentationContentRenderer { DocumentationMarkup(markup: $0.markup, parseUpToSection: .abstract) })?.abstractSection?.paragraph, let renderedContent = contentCompiler.visit(abstract).first, - case let .paragraph(inlines)? = renderedContent as? RenderBlockContent + case let .paragraph(p)? = renderedContent as? RenderBlockContent { - return inlines + return p.inlineContent } else { return [] } diff --git a/Sources/SwiftDocC/Model/Rendering/RenderContentCompiler.swift b/Sources/SwiftDocC/Model/Rendering/RenderContentCompiler.swift index 63baede9ac..e1ca6a039f 100644 --- a/Sources/SwiftDocC/Model/Rendering/RenderContentCompiler.swift +++ b/Sources/SwiftDocC/Model/Rendering/RenderContentCompiler.swift @@ -35,17 +35,17 @@ struct RenderContentCompiler: MarkupVisitor { mutating func visitBlockQuote(_ blockQuote: BlockQuote) -> [RenderContent] { let aside = Aside(blockQuote) - return [RenderBlockContent.aside(style: RenderBlockContent.AsideStyle(asideKind: aside.kind), - content: aside.content.reduce(into: [], { result, child in result.append(contentsOf: visit(child))}) as! [RenderBlockContent])] + return [RenderBlockContent.aside(.init(style: RenderBlockContent.AsideStyle(asideKind: aside.kind), + content: aside.content.reduce(into: [], { result, child in result.append(contentsOf: visit(child))}) as! [RenderBlockContent]))] } mutating func visitCodeBlock(_ codeBlock: CodeBlock) -> [RenderContent] { // Default to the bundle's code listing syntax if one is not explicitly declared in the code block. - return [RenderBlockContent.codeListing(syntax: codeBlock.language ?? bundle.info.defaultCodeListingLanguage, code: codeBlock.code.splitByNewlines, metadata: nil)] + return [RenderBlockContent.codeListing(.init(syntax: codeBlock.language ?? bundle.info.defaultCodeListingLanguage, code: codeBlock.code.splitByNewlines, metadata: nil))] } mutating func visitHeading(_ heading: Heading) -> [RenderContent] { - return [RenderBlockContent.heading(level: heading.level, text: heading.plainText, anchor: urlReadableFragment(heading.plainText))] + return [RenderBlockContent.heading(.init(level: heading.level, text: heading.plainText, anchor: urlReadableFragment(heading.plainText)))] } mutating func visitListItem(_ listItem: ListItem) -> [RenderContent] { @@ -55,7 +55,7 @@ struct RenderContentCompiler: MarkupVisitor { mutating func visitOrderedList(_ orderedList: OrderedList) -> [RenderContent] { let renderListItems = orderedList.listItems.reduce(into: [], { result, item in result.append(contentsOf: visitListItem(item))}) - return [RenderBlockContent.orderedList(items: renderListItems as! [RenderBlockContent.ListItem])] + return [RenderBlockContent.orderedList(.init(items: renderListItems as! [RenderBlockContent.ListItem]))] } mutating func visitUnorderedList(_ unorderedList: UnorderedList) -> [RenderContent] { @@ -64,7 +64,7 @@ struct RenderContentCompiler: MarkupVisitor { } mutating func visitParagraph(_ paragraph: Paragraph) -> [RenderContent] { - return [RenderBlockContent.paragraph(inlineContent: paragraph.children.reduce(into: [], { result, child in result.append(contentsOf: visit(child))}) as! [RenderInlineContent])] + return [RenderBlockContent.paragraph(.init(inlineContent: paragraph.children.reduce(into: [], { result, child in result.append(contentsOf: visit(child))}) as! [RenderInlineContent]))] } mutating func visitInlineCode(_ inlineCode: InlineCode) -> [RenderContent] { @@ -188,7 +188,7 @@ struct RenderContentCompiler: MarkupVisitor { var headerCells = [RenderBlockContent.TableRow.Cell]() for cell in table.head.cells { let cellContent = cell.children.reduce(into: [], { result, child in result.append(contentsOf: visit(child))}) - headerCells.append([RenderBlockContent.paragraph(inlineContent: cellContent as! [RenderInlineContent])]) + headerCells.append([RenderBlockContent.paragraph(.init(inlineContent: cellContent as! [RenderInlineContent]))]) } var rows = [RenderBlockContent.TableRow]() @@ -196,12 +196,12 @@ struct RenderContentCompiler: MarkupVisitor { var cells = [RenderBlockContent.TableRow.Cell]() for cell in row.cells { let cellContent = cell.children.reduce(into: [], { result, child in result.append(contentsOf: visit(child))}) - cells.append([RenderBlockContent.paragraph(inlineContent: cellContent as! [RenderInlineContent])]) + cells.append([RenderBlockContent.paragraph(.init(inlineContent: cellContent as! [RenderInlineContent]))]) } rows.append(RenderBlockContent.TableRow(cells: cells)) } - return [RenderBlockContent.table(header: .row, rows: [RenderBlockContent.TableRow(cells: headerCells)] + rows, metadata: nil)] + return [RenderBlockContent.table(.init(header: .row, rows: [RenderBlockContent.TableRow(cells: headerCells)] + rows, metadata: nil))] } mutating func visitStrikethrough(_ strikethrough: Strikethrough) -> [RenderContent] { @@ -229,11 +229,11 @@ struct RenderContentCompiler: MarkupVisitor { let lines = snippetMixin.lines[lineRange] let minimumIndentation = lines.map { $0.prefix { $0.isWhitespace }.count }.min() ?? 0 let trimmedLines = lines.map { String($0.dropFirst(minimumIndentation)) } - return [RenderBlockContent.codeListing(syntax: snippetMixin.language, code: trimmedLines, metadata: nil)] + return [RenderBlockContent.codeListing(.init(syntax: snippetMixin.language, code: trimmedLines, metadata: nil))] } else { // Render the whole snippet with its explanation content. let docCommentContent = snippetEntity.markup.children.flatMap { self.visit($0) } - let code = RenderBlockContent.codeListing(syntax: snippetMixin.language, code: snippetMixin.lines, metadata: nil) + let code = RenderBlockContent.codeListing(.init(syntax: snippetMixin.language, code: snippetMixin.lines, metadata: nil)) return docCommentContent + [code] } default: diff --git a/Sources/SwiftDocC/Model/Rendering/RenderNodeTranslator.swift b/Sources/SwiftDocC/Model/Rendering/RenderNodeTranslator.swift index 4b494574a8..ea3d765b74 100644 --- a/Sources/SwiftDocC/Model/Rendering/RenderNodeTranslator.swift +++ b/Sources/SwiftDocC/Model/Rendering/RenderNodeTranslator.swift @@ -88,7 +88,7 @@ public struct RenderNodeTranslator: SemanticVisitor { createAndRegisterRenderReference(forMedia: $0.source, altText: ($0 as? ImageMedia)?.altText) } - let result = [RenderBlockContent.step(content: renderBlock, caption: caption, media: mediaReference, code: codeReference, runtimePreview: previewReference)] + let result = [RenderBlockContent.step(.init(content: renderBlock, caption: caption, media: mediaReference, code: codeReference, runtimePreview: previewReference))] return result } diff --git a/Sources/SwiftDocC/Model/Rendering/Symbol/ContentRenderSection.swift b/Sources/SwiftDocC/Model/Rendering/Symbol/ContentRenderSection.swift index 01f7f2310a..8063e1ac77 100644 --- a/Sources/SwiftDocC/Model/Rendering/Symbol/ContentRenderSection.swift +++ b/Sources/SwiftDocC/Model/Rendering/Symbol/ContentRenderSection.swift @@ -24,7 +24,7 @@ public struct ContentRenderSection: RenderSection { self.kind = kind self.content = content if let heading = heading { - self.content.insert(RenderBlockContent.heading(level: 2, text: heading, anchor: urlReadableFragment(heading.lowercased())), at: 0) + self.content.insert(RenderBlockContent.heading(.init(level: 2, text: heading, anchor: urlReadableFragment(heading.lowercased()))), at: 0) } } diff --git a/Sources/SwiftDocC/Utility/FoundationExtensions/Sequence+RenderBlockContentElemenet.swift b/Sources/SwiftDocC/Utility/FoundationExtensions/Sequence+RenderBlockContentElemenet.swift index f498084aac..97e625a4aa 100644 --- a/Sources/SwiftDocC/Utility/FoundationExtensions/Sequence+RenderBlockContentElemenet.swift +++ b/Sources/SwiftDocC/Utility/FoundationExtensions/Sequence+RenderBlockContentElemenet.swift @@ -16,10 +16,10 @@ extension Sequence where Element == RenderBlockContent { /// This property is an empty array if the sequence doesn't contain a paragraph. var firstParagraph: [RenderInlineContent] { return mapFirst { blockContent in - guard case let .paragraph(inlineContent) = blockContent else { + guard case let .paragraph(p) = blockContent else { return nil } - return inlineContent + return p.inlineContent } ?? [] } } diff --git a/Tests/SwiftDocCTests/Indexing/IndexingTests.swift b/Tests/SwiftDocCTests/Indexing/IndexingTests.swift index 2e78c2a403..662e31da93 100644 --- a/Tests/SwiftDocCTests/Indexing/IndexingTests.swift +++ b/Tests/SwiftDocCTests/Indexing/IndexingTests.swift @@ -63,11 +63,11 @@ class IndexingTests: XCTestCase { func testTutorialSection() throws { var contentSection = ContentAndMediaSection(layout: .vertical, title: nil, media: RenderReferenceIdentifier("Image"), mediaPosition: .leading) - contentSection.content = [.paragraph(inlineContent: [.text("Hello, world!")])] + contentSection.content = [.paragraph(.init(inlineContent: [.text("Hello, world!")]))] let tutorialSectionsSection = TutorialSectionsRenderSection(sections: [ - .init(title: "Section 1", contentSection: [.contentAndMedia(content: contentSection)], stepsSection: [.paragraph(inlineContent: [.text("This is a step.")])], anchor: "section-1"), - .init(title: "Section 2", contentSection: [.contentAndMedia(content: contentSection)], stepsSection: [.paragraph(inlineContent: [.text("This is a step.")])], anchor: "section-2"), + .init(title: "Section 1", contentSection: [.contentAndMedia(content: contentSection)], stepsSection: [.paragraph(.init(inlineContent: [.text("This is a step.")]))], anchor: "section-1"), + .init(title: "Section 2", contentSection: [.contentAndMedia(content: contentSection)], stepsSection: [.paragraph(.init(inlineContent: [.text("This is a step.")]))], anchor: "section-2"), ]) let tutorialReference = ResolvedTopicReference(bundleIdentifier: "org.swift.docc.example", path: "/TestTutorial", sourceLanguage: .swift) let indexingRecords = try tutorialSectionsSection.indexingRecords(onPage: tutorialReference, references: [:]) @@ -143,45 +143,45 @@ class IndexingTests: XCTestCase { // MARK: - Blocks func testRenderBlockContentUnorderedList() { - let list = RenderBlockContent.unorderedList(items: [ + let list = RenderBlockContent.unorderedList(.init(items: [ .init(content: [ - .paragraph(inlineContent: [.text("Hello, ")]), + .paragraph(.init(inlineContent: [.text("Hello, ")])), ]), .init(content: [ - .paragraph(inlineContent: [.text("world!")]), + .paragraph(.init(inlineContent: [.text("world!")])), ]), - ]) + ])) XCTAssertEqual([], list.headings) XCTAssertEqual("Hello, world!", list.rawIndexableTextContent(references: [:])) } func testRenderBlockContentStep() { - let step = RenderBlockContent.step(content: [.paragraph(inlineContent: [.text("Hello, world!")])], caption: [.paragraph(inlineContent: [.text("Step caption")])], media: RenderReferenceIdentifier("Media"), code: RenderReferenceIdentifier("Code"), runtimePreview: RenderReferenceIdentifier("Preview")) + let step = RenderBlockContent.step(.init(content: [.paragraph(.init(inlineContent: [.text("Hello, world!")]))], caption: [.paragraph(.init(inlineContent: [.text("Step caption")]))], media: RenderReferenceIdentifier("Media"), code: RenderReferenceIdentifier("Code"), runtimePreview: RenderReferenceIdentifier("Preview"))) XCTAssertEqual([], step.headings) XCTAssertEqual("Hello, world! Step caption", step.rawIndexableTextContent(references: [:])) } func testRenderBlockContentParagraph() { - let paragraph = RenderBlockContent.paragraph(inlineContent: [.text("Hello, world!")]) + let paragraph = RenderBlockContent.paragraph(.init(inlineContent: [.text("Hello, world!")])) XCTAssertEqual([], paragraph.headings) XCTAssertEqual("Hello, world!", paragraph.rawIndexableTextContent(references: [:])) } func testRenderBlockContentOrderedList() { - let list = RenderBlockContent.orderedList(items: [ + let list = RenderBlockContent.orderedList(.init(items: [ .init(content: [ - .paragraph(inlineContent: [.text("Hello, ")]), + .paragraph(.init(inlineContent: [.text("Hello, ")])), ]), .init(content: [ - .paragraph(inlineContent: [.text("world!")]), + .paragraph(.init(inlineContent: [.text("world!")])), ]), - ]) + ])) XCTAssertEqual([], list.headings) XCTAssertEqual("Hello, world!", list.rawIndexableTextContent(references: [:])) } func testRenderBlockContentAside() { - let aside = RenderBlockContent.aside(style: .init(rawValue: "Experiment"), content: [.paragraph(inlineContent: [.text("Hello, world!")])]) + let aside = RenderBlockContent.aside(.init(style: .init(rawValue: "Experiment"), content: [.paragraph(.init(inlineContent: [.text("Hello, world!")]))])) XCTAssertEqual([], aside.headings) XCTAssertEqual("Hello, world!", aside.rawIndexableTextContent(references: [:])) } diff --git a/Tests/SwiftDocCTests/Infrastructure/ReferenceResolverTests.swift b/Tests/SwiftDocCTests/Infrastructure/ReferenceResolverTests.swift index 0aa49a12ae..6b601f2ec1 100644 --- a/Tests/SwiftDocCTests/Infrastructure/ReferenceResolverTests.swift +++ b/Tests/SwiftDocCTests/Infrastructure/ReferenceResolverTests.swift @@ -238,18 +238,18 @@ class ReferenceResolverTests: XCTestCase { }! let items = discussion.content.mapFirst(where: { block -> [RenderBlockContent.ListItem]? in - guard case RenderBlockContent.unorderedList(items: let items) = block else { + guard case RenderBlockContent.unorderedList(let l) = block else { return nil } - return items + return l.items })! let inlineItems = items.compactMap { listItem in return listItem.content.mapFirst { block -> RenderInlineContent? in - guard case RenderBlockContent.paragraph(inlineContent: let inlineItems) = block else { + guard case RenderBlockContent.paragraph(let p) = block else { return nil } - return inlineItems.first + return p.inlineContent.first } } diff --git a/Tests/SwiftDocCTests/Model/RenderContentMetadataTests.swift b/Tests/SwiftDocCTests/Model/RenderContentMetadataTests.swift index 61939faf51..031040d14d 100644 --- a/Tests/SwiftDocCTests/Model/RenderContentMetadataTests.swift +++ b/Tests/SwiftDocCTests/Model/RenderContentMetadataTests.swift @@ -37,16 +37,16 @@ class RenderContentMetadataTests: XCTestCase { RenderInlineContent.text("Content"), ]) - let table = RenderBlockContent.table(header: .both, rows: [], metadata: metadata) + let table = RenderBlockContent.table(.init(header: .both, rows: [], metadata: metadata)) let data = try JSONEncoder().encode(table) let roundtrip = try JSONDecoder().decode(RenderBlockContent.self, from: data) - guard case RenderBlockContent.table(_, _, let metadataRoundtrip) = roundtrip else { + guard case RenderBlockContent.table(let t) = roundtrip else { XCTFail("Didn't decode table correctly") return } - XCTAssertEqual(metadata, metadataRoundtrip) + XCTAssertEqual(metadata, t.metadata) } func testCodeListingMetadata() throws { @@ -54,16 +54,16 @@ class RenderContentMetadataTests: XCTestCase { RenderInlineContent.text("Content"), ]) - let code = RenderBlockContent.codeListing(syntax: nil, code: [], metadata: metadata) + let code = RenderBlockContent.codeListing(.init(syntax: nil, code: [], metadata: metadata)) let data = try JSONEncoder().encode(code) let roundtrip = try JSONDecoder().decode(RenderBlockContent.self, from: data) - guard case RenderBlockContent.codeListing(_, _, let metadataRoundtrip) = roundtrip else { + guard case RenderBlockContent.codeListing(let roundtripListing) = roundtrip else { XCTFail("Didn't decode code listing correctly") return } - XCTAssertEqual(metadata, metadataRoundtrip) + XCTAssertEqual(metadata, roundtripListing.metadata) } func testRenderingTables() throws { @@ -86,8 +86,8 @@ class RenderContentMetadataTests: XCTestCase { let renderCell: ([RenderBlockContent]) -> String = { cell in return cell.reduce(into: "") { (result, element) in switch element { - case .paragraph(inlineContent: let els): - guard let para = els.first else { return } + case .paragraph(let p): + guard let para = p.inlineContent.first else { return } result.append(para.plainText) default: XCTFail("Unexpected element"); return } @@ -95,13 +95,13 @@ class RenderContentMetadataTests: XCTestCase { } switch renderedTable { - case .table(let header, let rows, _): - XCTAssertEqual(header, .row) - XCTAssertEqual(rows.count, 3) - guard rows.count == 3 else { return } - XCTAssertEqual(rows[0].cells.map(renderCell), ["Column 1", "Column 2"]) - XCTAssertEqual(rows[1].cells.map(renderCell), ["Cell 1", "Cell 2"]) - XCTAssertEqual(rows[2].cells.map(renderCell), ["Cell 3", "Cell 4"]) + case .table(let t): + XCTAssertEqual(t.header, .row) + XCTAssertEqual(t.rows.count, 3) + guard t.rows.count == 3 else { return } + XCTAssertEqual(t.rows[0].cells.map(renderCell), ["Column 1", "Column 2"]) + XCTAssertEqual(t.rows[1].cells.map(renderCell), ["Cell 1", "Cell 2"]) + XCTAssertEqual(t.rows[2].cells.map(renderCell), ["Cell 3", "Cell 4"]) default: XCTFail("Unexpected element") } } diff --git a/Tests/SwiftDocCTests/Model/RenderNodeSerializationTests.swift b/Tests/SwiftDocCTests/Model/RenderNodeSerializationTests.swift index 5331628f68..b1d4bad8ba 100644 --- a/Tests/SwiftDocCTests/Model/RenderNodeSerializationTests.swift +++ b/Tests/SwiftDocCTests/Model/RenderNodeSerializationTests.swift @@ -37,24 +37,24 @@ class RenderNodeSerializationTests: XCTestCase { ] let blockContent: [RenderBlockContent] = [ - .paragraph(inlineContent: inlines), - .aside(style: .init(rawValue: "Experiment"), content: [ - .paragraph(inlineContent: [ + .paragraph(.init(inlineContent: inlines)), + .aside(.init(style: .init(rawValue: "Experiment"), content: [ + .paragraph(.init(inlineContent: [ .text("Try running the project in the Simulator using the "), .strong(inlineContent: [.text("Project > Run")]), .text(" menu item, or the following code:"), - ]), - .codeListing(syntax: "swift", code: ["xcrun xcodebuild -h", "xcrun xcodebuild build -configuration Debug"], metadata: nil), - ]) + ])), + .codeListing(.init(syntax: "swift", code: ["xcrun xcodebuild -h", "xcrun xcodebuild build -configuration Debug"], metadata: nil)), + ])) ] let steps: [RenderBlockContent] = [ - .paragraph(inlineContent: [.text("After you download Xcode, create a project.")]), - .step(content: [.paragraph(inlineContent: [.text("Lorem ipsum")])], caption: [.paragraph(inlineContent: [.text("Caption")])], media: .init("screenshot2.png"), code: nil, runtimePreview: nil), - .step(content: [.paragraph(inlineContent: [.text("Lorem ipsum")])], caption: [], media: nil, code: .init("helloworld.swift"), runtimePreview: .init("screenshot2.png")), - .step(content: [.paragraph(inlineContent: [.text("Lorem ipsum")])], caption: [], media: .init("screenshot3.png"), code: nil, runtimePreview: nil), - .aside(style: .init(rawValue: "Note"), content: [.paragraph(inlineContent: [.text("Lorem ipsum dolor emit.")])]), - .step(content: [.paragraph(inlineContent: [.text("Lorem ipsum")])], caption: [], media: .init("screenshot4.png"), code: nil, runtimePreview: nil), + .paragraph(.init(inlineContent: [.text("After you download Xcode, create a project.")])), + .step(.init(content: [.paragraph(.init(inlineContent: [.text("Lorem ipsum")]))], caption: [.paragraph(.init(inlineContent: [.text("Caption")]))], media: .init("screenshot2.png"), code: nil, runtimePreview: nil)), + .step(.init(content: [.paragraph(.init(inlineContent: [.text("Lorem ipsum")]))], caption: [], media: nil, code: .init("helloworld.swift"), runtimePreview: .init("screenshot2.png"))), + .step(.init(content: [.paragraph(.init(inlineContent: [.text("Lorem ipsum")]))], caption: [], media: .init("screenshot3.png"), code: nil, runtimePreview: nil)), + .aside(.init(style: .init(rawValue: "Note"), content: [.paragraph(.init(inlineContent: [.text("Lorem ipsum dolor emit.")]))])), + .step(.init(content: [.paragraph(.init(inlineContent: [.text("Lorem ipsum")]))], caption: [], media: .init("screenshot4.png"), code: nil, runtimePreview: nil)), ] var contentAndMedia = ContentAndMediaSection(layout: .horizontal, title: "", media: RenderReferenceIdentifier("screenshot1.png"), mediaPosition: .leading) @@ -68,20 +68,20 @@ class RenderNodeSerializationTests: XCTestCase { inputNode.sections.append(tutorialSectionsSection) - let assessment1 = TutorialAssessmentsRenderSection.Assessment(title: [.paragraph(inlineContent: [.text("Lorem ipsum dolor sit amet?")])], + let assessment1 = TutorialAssessmentsRenderSection.Assessment(title: [.paragraph(.init(inlineContent: [.text("Lorem ipsum dolor sit amet?")]))], content: nil, choices: [ - .init(content: [.codeListing(syntax: "swift", code: ["override func viewDidLoad() {", "super.viewDidLoad()", "}"], metadata: nil)], isCorrect: true, justification: [.paragraph(inlineContent: [.text("It's correct because...")])], reaction: "That's right!"), - .init(content: [.codeListing(syntax: "swift", code: ["sceneView.delegate = self"], metadata: nil)], isCorrect: false, justification: [.paragraph(inlineContent: [.text("It's incorrect because...")])], reaction: "Not quite."), - .init(content: [.paragraph(inlineContent: [.text("None of the above.")])], isCorrect: false, justification: [.paragraph(inlineContent: [.text("It's incorrect because...")])], reaction: nil), + .init(content: [.codeListing(.init(syntax: "swift", code: ["override func viewDidLoad() {", "super.viewDidLoad()", "}"], metadata: nil))], isCorrect: true, justification: [.paragraph(.init(inlineContent: [.text("It's correct because...")]))], reaction: "That's right!"), + .init(content: [.codeListing(.init(syntax: "swift", code: ["sceneView.delegate = self"], metadata: nil))], isCorrect: false, justification: [.paragraph(.init(inlineContent: [.text("It's incorrect because...")]))], reaction: "Not quite."), + .init(content: [.paragraph(.init(inlineContent: [.text("None of the above.")]))], isCorrect: false, justification: [.paragraph(.init(inlineContent: [.text("It's incorrect because...")]))], reaction: nil), ]) - let assessment2 = TutorialAssessmentsRenderSection.Assessment(title: [.paragraph(inlineContent: [.text("Duis aute irure dolor in reprehenderit?")])], - content: [.paragraph(inlineContent: [.text("What is the airspeed velocity of an unladen swallow?")])], + let assessment2 = TutorialAssessmentsRenderSection.Assessment(title: [.paragraph(.init(inlineContent: [.text("Duis aute irure dolor in reprehenderit?")]))], + content: [.paragraph(.init(inlineContent: [.text("What is the airspeed velocity of an unladen swallow?")]))], choices: [ - .init(content: [.codeListing(syntax: "swift", code: ["super.viewWillAppear()"], metadata: nil)], isCorrect: true, justification: [.paragraph(inlineContent: [.text("It's correct because...")])], reaction: "Correct."), - .init(content: [.codeListing(syntax: "swift", code: ["sceneView.delegate = self"], metadata: nil)], isCorrect: true, justification: [.paragraph(inlineContent: [.text("It's correct because...")])], reaction: "Yep."), - .init(content: [.paragraph(inlineContent: [.text("None of the above.")])], isCorrect: false, justification: [.paragraph(inlineContent: [.text("It's incorrect because...")])], reaction: "Close!"), + .init(content: [.codeListing(.init(syntax: "swift", code: ["super.viewWillAppear()"], metadata: nil))], isCorrect: true, justification: [.paragraph(.init(inlineContent: [.text("It's correct because...")]))], reaction: "Correct."), + .init(content: [.codeListing(.init(syntax: "swift", code: ["sceneView.delegate = self"], metadata: nil))], isCorrect: true, justification: [.paragraph(.init(inlineContent: [.text("It's correct because...")]))], reaction: "Yep."), + .init(content: [.paragraph(.init(inlineContent: [.text("None of the above.")]))], isCorrect: false, justification: [.paragraph(.init(inlineContent: [.text("It's incorrect because...")]))], reaction: "Close!"), ]) let assessments = TutorialAssessmentsRenderSection(assessments: [assessment1, assessment2], anchor: "Check-Your-Understanding") diff --git a/Tests/SwiftDocCTests/Model/SemaToRenderNodeTests.swift b/Tests/SwiftDocCTests/Model/SemaToRenderNodeTests.swift index 825d8a2b09..23e1074b7a 100644 --- a/Tests/SwiftDocCTests/Model/SemaToRenderNodeTests.swift +++ b/Tests/SwiftDocCTests/Model/SemaToRenderNodeTests.swift @@ -68,27 +68,29 @@ class SemaToRenderNodeTests: XCTestCase { do { let contentSection = tutorialSections.tasks[0].contentSection[0] guard case let .contentAndMedia(section) = contentSection, - case let .aside(note, noteContent) = section.content[1], - note == .init(rawValue: "Note"), - case let .aside(important, importantContent) = section.content[2], - important == .init(rawValue: "Important") else { + case let .aside(noteAside) = section.content[1], + noteAside.style == .init(rawValue: "Note"), + case let .aside(importantAside) = section.content[2], + importantAside.style == .init(rawValue: "Important") else { XCTFail("Expected `Note` and `Important` asides") return } + let noteContent = noteAside.content + let importantContent = importantAside.content XCTAssertEqual(1, noteContent.count) - guard case let .paragraph(noteInlines)? = noteContent.first, - noteInlines.count == 1, - case let .text(noteText)? = noteInlines.first else { + guard case let .paragraph(notePara)? = noteContent.first, + notePara.inlineContent.count == 1, + case let .text(noteText)? = notePara.inlineContent.first else { XCTFail("Expected single paragraph with single inline text at the start of a 'note' aside") return } XCTAssertEqual("This is a note.", noteText) XCTAssertEqual(1, importantContent.count) - guard case let .paragraph(importantInlines)? = importantContent.first, - noteInlines.count == 1, - case let .text(importantText)? = importantInlines.first else { + guard case let .paragraph(importantPara)? = importantContent.first, + importantPara.inlineContent.count == 1, + case let .text(importantText)? = importantPara.inlineContent.first else { XCTFail("Expected single paragraph with single inline text at the start of a 'important' aside") return } @@ -97,12 +99,16 @@ class SemaToRenderNodeTests: XCTestCase { let stepsSection = tutorialSections.tasks[0].stepsSection - guard case .step(_, let caption, let step1Media, let step1Code, let step1RuntimePreview) = stepsSection[2] else { + guard case .step(let s) = stepsSection[2] else { XCTFail("Expected step") return } + let caption = s.caption + let step1Media = s.media + let step1Code = s.code + let step1RuntimePreview = s.runtimePreview - guard case .paragraph(let inlineContent)? = caption.first, case .text(let captionText)? = inlineContent.first else { + guard case .paragraph(let captionPara)? = caption.first, case .text(let captionText)? = captionPara.inlineContent.first else { XCTFail("Expected step caption") return } @@ -128,23 +134,23 @@ class SemaToRenderNodeTests: XCTestCase { XCTFail("Missing paragraph of content for first choice of first assessment.") return } - XCTAssertEqual(firstChoiceContentParagraph, [RenderInlineContent.codeVoice(code: "anchor.hitTest(view)")]) + XCTAssertEqual(firstChoiceContentParagraph.inlineContent, [RenderInlineContent.codeVoice(code: "anchor.hitTest(view)")]) guard case RenderBlockContent.paragraph(let firstChoiceJustificationContentParagraph)? = firstAssessment.choices.first?.justification?.first else { XCTFail("Missing paragraph of justification for first choice of first assessment.") return } - XCTAssertEqual(firstChoiceJustificationContentParagraph, [RenderInlineContent.text("This is correct because it is.")]) + XCTAssertEqual(firstChoiceJustificationContentParagraph.inlineContent, [RenderInlineContent.text("This is correct because it is.")]) guard case RenderBlockContent.paragraph(let lastChoiceContentParagraph)? = firstAssessment.choices.last?.content.first else { XCTFail("Missing paragraph of content for last choice of first assessment.") return } - XCTAssertEqual(lastChoiceContentParagraph, [RenderInlineContent.codeVoice(code: "anchor.intersects(view)")]) + XCTAssertEqual(lastChoiceContentParagraph.inlineContent, [RenderInlineContent.codeVoice(code: "anchor.intersects(view)")]) guard case RenderBlockContent.paragraph(let lastChoiceJustificationContentParagraph)? = firstAssessment.choices.last?.justification?.first else { XCTFail("Missing paragraph of justification for last choice of first assessment.") return } - XCTAssertEqual(lastChoiceJustificationContentParagraph, [RenderInlineContent.text("This is incorrect because it is.")]) + XCTAssertEqual(lastChoiceJustificationContentParagraph.inlineContent, [RenderInlineContent.text("This is incorrect because it is.")]) XCTAssertEqual(renderNode.references.count, 33) guard let simpleImageReference = renderNode.references["figure1"] as? ImageReference else { @@ -478,9 +484,9 @@ class SemaToRenderNodeTests: XCTestCase { private func makeListItem(reference: String) -> RenderBlockContent.ListItem { return RenderBlockContent.ListItem(content: [ - RenderBlockContent.paragraph(inlineContent: [ + RenderBlockContent.paragraph(.init(inlineContent: [ .reference(identifier: .init(reference), isActive: true, overridingTitle: nil, overridingTitleInlineContent: nil), - ]), + ])), ]) } @@ -658,42 +664,44 @@ class SemaToRenderNodeTests: XCTestCase { XCTAssertEqual(resources.tiles.count, 5) XCTAssertEqual(tiles[0].title, "Documentation") - guard case .unorderedList(let tile0Items) = tiles[0].content[1] else { + guard case .unorderedList(let tile0List) = tiles[0].content[1] else { XCTFail() return } + let tile0Items = tile0List.items XCTAssertEqual(tile0Items.count, 2) XCTAssertEqual(tile0Items[0], makeListItem(reference: "doc://org.swift.docc.example/tutorials/Test-Bundle/TestTutorial")) XCTAssertEqual(tile0Items[1], makeListItem(reference: "doc://org.swift.docc.example/tutorials/Test-Bundle/TestTutorial2")) XCTAssertEqual(tiles[1].title, "Sample Code") - guard case .unorderedList(let tile1Items) = tiles[1].content[1] else { + guard case .unorderedList(let tile1List) = tiles[1].content[1] else { XCTFail() return } + let tile1Items = tile1List.items XCTAssertEqual(tile1Items.count, 2) XCTAssertEqual(tile1Items[0], makeListItem(reference: "doc://org.swift.docc.example/tutorials/Test-Bundle/TestTutorial")) XCTAssertEqual(tile1Items[1], makeListItem(reference: "doc://org.swift.docc.example/tutorials/Test-Bundle/TestTutorial2")) XCTAssertEqual(tiles[2].title, "Xcode and SDKs") - guard case .paragraph(let tile2InlineContent) = tiles[2].content[0] else { + guard case .paragraph(let tile2Paragraph) = tiles[2].content[0] else { XCTFail() return } - XCTAssertEqual(tile2InlineContent, [RenderInlineContent.text("Download Xcode 10, which includes the latest tools and SDKs.")]) + XCTAssertEqual(tile2Paragraph.inlineContent, [RenderInlineContent.text("Download Xcode 10, which includes the latest tools and SDKs.")]) XCTAssertEqual(tiles[3].title, "Videos") - guard case .paragraph(let tile3InlineContent) = tiles[3].content[0] else { + guard case .paragraph(let tile3Paragraph) = tiles[3].content[0] else { XCTFail() return } - XCTAssertEqual(tile3InlineContent, [RenderInlineContent.text("See AR presentation from WWDC and other events.")]) + XCTAssertEqual(tile3Paragraph.inlineContent, [RenderInlineContent.text("See AR presentation from WWDC and other events.")]) - guard case .paragraph(let tile4InlineContent) = tiles[4].content[0] else { + guard case .paragraph(let tile4Paragraph) = tiles[4].content[0] else { XCTFail() return } - XCTAssertEqual(tile4InlineContent, [RenderInlineContent.text("Discuss AR with Apple engineers and other developers.")]) + XCTAssertEqual(tile4Paragraph.inlineContent, [RenderInlineContent.text("Discuss AR with Apple engineers and other developers.")]) XCTAssertEqual(renderNode.metadata.title, "Technology X") @@ -1042,7 +1050,7 @@ class SemaToRenderNodeTests: XCTestCase { // Test all identifiers have been resolved to the ``MyClass`` symbol XCTAssertEqual(renderNode.topicSections[0].title, "Task Group Excercising Symbol Links") - XCTAssertEqual(renderNode.topicSections[0].abstract?.map{ RenderBlockContent.paragraph(inlineContent: [$0]) }.paragraphText.joined(), "Task Group abstract text.") + XCTAssertEqual(renderNode.topicSections[0].abstract?.map{ RenderBlockContent.paragraph(.init(inlineContent: [$0])) }.paragraphText.joined(), "Task Group abstract text.") guard let discussion = renderNode.topicSections[0].discussion as? ContentRenderSection else { XCTFail("Could not find group discussion") @@ -1068,8 +1076,8 @@ class SemaToRenderNodeTests: XCTestCase { // Check the code sample in the discussion XCTAssertTrue(discussion.content.last.map { block -> Bool in switch block { - case .codeListing(let syntax, let code, _): - return syntax == "swift" && code.first == "struct MyClass : MyProtocol" + case .codeListing(let l): + return l.syntax == "swift" && l.code.first == "struct MyClass : MyProtocol" default: return false } } ?? false) @@ -1086,7 +1094,7 @@ class SemaToRenderNodeTests: XCTestCase { // Test all identifiers have been resolved to the ``MyClass`` symbol XCTAssertEqual(renderNode.seeAlsoSections[0].title, "Related Documentation") - XCTAssertEqual(renderNode.seeAlsoSections[0].abstract?.map{ RenderBlockContent.paragraph(inlineContent: [$0]) }.paragraphText.joined(), "Further Reading abstract text.") + XCTAssertEqual(renderNode.seeAlsoSections[0].abstract?.map{ RenderBlockContent.paragraph(.init(inlineContent: [$0])) }.paragraphText.joined(), "Further Reading abstract text.") XCTAssertNil(renderNode.seeAlsoSections[0].discussion) guard renderNode.seeAlsoSections[0].identifiers.count == 5 else { XCTFail("The amount of identifiers in See Also was not expected") @@ -1686,17 +1694,17 @@ Document @1:1-11:19 var contentTranslator = RenderContentCompiler(context: context, bundle: bundle, identifier: ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/TestTutorial", sourceLanguage: .swift)) let renderContent = try XCTUnwrap(markup.children.reduce(into: [], { result, item in result.append(contentsOf: contentTranslator.visit(item))}) as? [RenderBlockContent]) let expectedContent: [RenderBlockContent] = [ - .paragraph(inlineContent: [ - RenderInlineContent.text("This is some text.")]), - .unorderedList(items: [ + .paragraph(.init(inlineContent: [ + RenderInlineContent.text("This is some text.")])), + .unorderedList(.init(items: [ RenderBlockContent.ListItem(content: [ - .paragraph(inlineContent: [ - .text("The next directives should get dropped.")])])]), - .unorderedList(items: [ + .paragraph(.init(inlineContent: [ + .text("The next directives should get dropped.")]))])])), + .unorderedList(.init(items: [ RenderBlockContent.ListItem(content: [ - .paragraph(inlineContent: [ - .text("@MyOtherDirective")])])]), - .paragraph(inlineContent: [.text("This is more text.")]), + .paragraph(.init(inlineContent: [ + .text("@MyOtherDirective")]))])])), + .paragraph(.init(inlineContent: [.text("This is more text.")])), ] XCTAssertEqual(expectedContent, renderContent) } @@ -2263,8 +2271,8 @@ Document @1:1-11:19 let contentSection = section as? ContentRenderSection, !contentSection.content.isEmpty else { return false } switch contentSection.content[0] { - case .heading(let level, let text, let anchor): - return level == 2 && text == "Return Value" && anchor == "return-value" + case .heading(let h): + return h.level == 2 && h.text == "Return Value" && h.anchor == "return-value" default: return false } }) @@ -2302,29 +2310,29 @@ Document @1:1-11:19 } let asidesStressTest: [RenderBlockContent] = [ - .aside(style: .init(rawValue: "Note"), content: [.paragraph(inlineContent: [.text("This is a note.")])]), - .aside(style: .init(rawValue: "Tip"), content: [.paragraph(inlineContent: [.text("Here’s a tip.")])]), - .aside(style: .init(rawValue: "Important"), content: [.paragraph(inlineContent: [.text("Keep this in mind.")])]), - .aside(style: .init(rawValue: "Experiment"), content: [.paragraph(inlineContent: [.text("Try this out.")])]), - .aside(style: .init(rawValue: "Warning"), content: [.paragraph(inlineContent: [.text("Watch out for this.")])]), - .aside(style: .init(rawValue: "Attention"), content: [.paragraph(inlineContent: [.text("Head’s up!")])]), - .aside(style: .init(rawValue: "Author"), content: [.paragraph(inlineContent: [.text("I wrote this.")])]), - .aside(style: .init(rawValue: "Authors"), content: [.paragraph(inlineContent: [.text("We wrote this.")])]), - .aside(style: .init(rawValue: "Bug"), content: [.paragraph(inlineContent: [.text("This is wrong.")])]), - .aside(style: .init(rawValue: "Complexity"), content: [.paragraph(inlineContent: [.text("This takes time.")])]), - .aside(style: .init(rawValue: "Copyright"), content: [.paragraph(inlineContent: [.text("2021 Apple Inc.")])]), - .aside(style: .init(rawValue: "Date"), content: [.paragraph(inlineContent: [.text("1 January 1970")])]), - .aside(style: .init(rawValue: "Invariant"), content: [.paragraph(inlineContent: [.text("This shouldn’t change.")])]), - .aside(style: .init(rawValue: "MutatingVariant"), content: [.paragraph(inlineContent: [.text("This will change.")])]), - .aside(style: .init(rawValue: "NonMutatingVariant"), content: [.paragraph(inlineContent: [.text("This changes, but not in the data.")])]), - .aside(style: .init(rawValue: "Postcondition"), content: [.paragraph(inlineContent: [.text("After calling, this should be true.")])]), - .aside(style: .init(rawValue: "Precondition"), content: [.paragraph(inlineContent: [.text("Before calling, this should be true.")])]), - .aside(style: .init(rawValue: "Remark"), content: [.paragraph(inlineContent: [.text("Something you should know.")])]), - .aside(style: .init(rawValue: "Requires"), content: [.paragraph(inlineContent: [.text("This needs something.")])]), - .aside(style: .init(rawValue: "Since"), content: [.paragraph(inlineContent: [.text("The beginning of time.")])]), - .aside(style: .init(rawValue: "Todo"), content: [.paragraph(inlineContent: [.text("This needs work.")])]), - .aside(style: .init(rawValue: "Version"), content: [.paragraph(inlineContent: [.text("3.1.4")])]), - .aside(style: .init(rawValue: "Throws"), content: [.paragraph(inlineContent: [.text("A serious error.")])]), + .aside(.init(style: .init(rawValue: "Note"), content: [.paragraph(.init(inlineContent: [.text("This is a note.")]))])), + .aside(.init(style: .init(rawValue: "Tip"), content: [.paragraph(.init(inlineContent: [.text("Here’s a tip.")]))])), + .aside(.init(style: .init(rawValue: "Important"), content: [.paragraph(.init(inlineContent: [.text("Keep this in mind.")]))])), + .aside(.init(style: .init(rawValue: "Experiment"), content: [.paragraph(.init(inlineContent: [.text("Try this out.")]))])), + .aside(.init(style: .init(rawValue: "Warning"), content: [.paragraph(.init(inlineContent: [.text("Watch out for this.")]))])), + .aside(.init(style: .init(rawValue: "Attention"), content: [.paragraph(.init(inlineContent: [.text("Head’s up!")]))])), + .aside(.init(style: .init(rawValue: "Author"), content: [.paragraph(.init(inlineContent: [.text("I wrote this.")]))])), + .aside(.init(style: .init(rawValue: "Authors"), content: [.paragraph(.init(inlineContent: [.text("We wrote this.")]))])), + .aside(.init(style: .init(rawValue: "Bug"), content: [.paragraph(.init(inlineContent: [.text("This is wrong.")]))])), + .aside(.init(style: .init(rawValue: "Complexity"), content: [.paragraph(.init(inlineContent: [.text("This takes time.")]))])), + .aside(.init(style: .init(rawValue: "Copyright"), content: [.paragraph(.init(inlineContent: [.text("2021 Apple Inc.")]))])), + .aside(.init(style: .init(rawValue: "Date"), content: [.paragraph(.init(inlineContent: [.text("1 January 1970")]))])), + .aside(.init(style: .init(rawValue: "Invariant"), content: [.paragraph(.init(inlineContent: [.text("This shouldn’t change.")]))])), + .aside(.init(style: .init(rawValue: "MutatingVariant"), content: [.paragraph(.init(inlineContent: [.text("This will change.")]))])), + .aside(.init(style: .init(rawValue: "NonMutatingVariant"), content: [.paragraph(.init(inlineContent: [.text("This changes, but not in the data.")]))])), + .aside(.init(style: .init(rawValue: "Postcondition"), content: [.paragraph(.init(inlineContent: [.text("After calling, this should be true.")]))])), + .aside(.init(style: .init(rawValue: "Precondition"), content: [.paragraph(.init(inlineContent: [.text("Before calling, this should be true.")]))])), + .aside(.init(style: .init(rawValue: "Remark"), content: [.paragraph(.init(inlineContent: [.text("Something you should know.")]))])), + .aside(.init(style: .init(rawValue: "Requires"), content: [.paragraph(.init(inlineContent: [.text("This needs something.")]))])), + .aside(.init(style: .init(rawValue: "Since"), content: [.paragraph(.init(inlineContent: [.text("The beginning of time.")]))])), + .aside(.init(style: .init(rawValue: "Todo"), content: [.paragraph(.init(inlineContent: [.text("This needs work.")]))])), + .aside(.init(style: .init(rawValue: "Version"), content: [.paragraph(.init(inlineContent: [.text("3.1.4")]))])), + .aside(.init(style: .init(rawValue: "Throws"), content: [.paragraph(.init(inlineContent: [.text("A serious error.")]))])), ] func testBareTechnology() throws { @@ -2617,12 +2625,12 @@ Document @1:1-11:19 // Verify the discussion was inherited. let discussion = try XCTUnwrap(renderNode.primaryContentSections[1] as? ContentRenderSection) XCTAssertEqual(discussion.content, [ - RenderBlockContent.heading(level: 2, text: "Discussion", anchor: "discussion"), - .paragraph(inlineContent: [ + RenderBlockContent.heading(.init(level: 2, text: "Discussion", anchor: "discussion")), + .paragraph(.init(inlineContent: [ .text("Doc extension discussion. Missing: "), .image(identifier: RenderReferenceIdentifier("my-inherited-image.png"), metadata: nil), .text("."), - ]) + ])) ]) } } @@ -2792,12 +2800,12 @@ Document @1:1-11:19 // Verify the discussion was inherited. let discussion = try XCTUnwrap(renderNode.primaryContentSections[1] as? ContentRenderSection) XCTAssertEqual(discussion.content, [ - RenderBlockContent.heading(level: 2, text: "Discussion", anchor: "discussion"), - .paragraph(inlineContent: [ + RenderBlockContent.heading(.init(level: 2, text: "Discussion", anchor: "discussion")), + .paragraph(.init(inlineContent: [ .text("Inherited discussion. Missing: "), .image(identifier: RenderReferenceIdentifier("my-inherited-image.png"), metadata: nil), .text("."), - ]), + ])), ]) } } diff --git a/Tests/SwiftDocCTests/Rendering/CustomFormattingRenderElementsTests.swift b/Tests/SwiftDocCTests/Rendering/CustomFormattingRenderElementsTests.swift index 0660d25d81..03348c2092 100644 --- a/Tests/SwiftDocCTests/Rendering/CustomFormattingRenderElementsTests.swift +++ b/Tests/SwiftDocCTests/Rendering/CustomFormattingRenderElementsTests.swift @@ -31,7 +31,7 @@ class CustomFormattingRenderElementsTests: XCTestCase { return } - XCTAssertEqual(firstParagraph, [ + XCTAssertEqual(firstParagraph.inlineContent, [ .text("Use "), .newTerm(inlineContent: [.text("www")]), .text(" and "), @@ -39,20 +39,20 @@ class CustomFormattingRenderElementsTests: XCTestCase { .text("."), ]) - guard case RenderBlockContent.termList(let items) = discussion.content[2] else { + guard case RenderBlockContent.termList(let l) = discussion.content[2] else { XCTFail("Didn't find term list") return } - XCTAssertEqual(items, [ + XCTAssertEqual(l.items, [ RenderBlockContent.TermListItem( term: .init(inlineContent: [ .text("This is a term"), ]), definition: .init(content: [ - .paragraph(inlineContent: [ + .paragraph(.init(inlineContent: [ .text("This is a definition"), - ]), + ])), ])), ]) } diff --git a/Tests/SwiftDocCTests/Rendering/DefaultCodeListingSyntaxTests.swift b/Tests/SwiftDocCTests/Rendering/DefaultCodeListingSyntaxTests.swift index 81a619c666..317945bbd1 100644 --- a/Tests/SwiftDocCTests/Rendering/DefaultCodeListingSyntaxTests.swift +++ b/Tests/SwiftDocCTests/Rendering/DefaultCodeListingSyntaxTests.swift @@ -65,8 +65,8 @@ class DefaultCodeBlockSyntaxTests: XCTestCase { } private func codeListing(at index: Int, in renderSection: ContentRenderSection, file: StaticString = #file, line: UInt = #line) throws -> CodeListing { - if case let .codeListing(language, lines, _) = renderSection.content[index] { - return CodeListing(language: language, lines: lines) + if case let .codeListing(l) = renderSection.content[index] { + return CodeListing(language: l.syntax, lines: l.code) } XCTFail("Expected code listing at index \(index)", file: (file), line: line) diff --git a/Tests/SwiftDocCTests/Rendering/ExternalLinkTitleTests.swift b/Tests/SwiftDocCTests/Rendering/ExternalLinkTitleTests.swift index 98937635aa..7e5629eb70 100644 --- a/Tests/SwiftDocCTests/Rendering/ExternalLinkTitleTests.swift +++ b/Tests/SwiftDocCTests/Rendering/ExternalLinkTitleTests.swift @@ -40,13 +40,13 @@ public class ExternalLinkTitleTests: XCTestCase { let (translator, content) = try getTranslatorAndBlockContentForMarkup(markupSource) - guard case let .paragraph(paragraphContent) = content[1] else { + guard case let .paragraph(firstParagraph) = content[1] else { XCTFail("Unexpected render tree.") return } let expectedReferenceIdentifier = RenderReferenceIdentifier.init(forExternalLink: "https://www.example.com") - XCTAssertEqual(paragraphContent[1], RenderInlineContent.reference(identifier: expectedReferenceIdentifier, isActive: true, overridingTitle: nil, overridingTitleInlineContent: nil)) + XCTAssertEqual(firstParagraph.inlineContent[1], RenderInlineContent.reference(identifier: expectedReferenceIdentifier, isActive: true, overridingTitle: nil, overridingTitleInlineContent: nil)) let linkReference = translator.linkReferences[expectedReferenceIdentifier.identifier] XCTAssertNotNil(linkReference, "Link reference should have been collected by translator.") @@ -67,13 +67,13 @@ public class ExternalLinkTitleTests: XCTestCase { let (translator, content) = try getTranslatorAndBlockContentForMarkup(markupSource) - guard case let .paragraph(paragraphContent) = content[1] else { + guard case let .paragraph(firstParagraph) = content[1] else { XCTFail("Unexpected render tree.") return } let expectedReferenceIdentifier = RenderReferenceIdentifier.init(forExternalLink: "https://www.example.com") - XCTAssertEqual(paragraphContent[1], RenderInlineContent.reference(identifier: expectedReferenceIdentifier, isActive: true, overridingTitle: nil, overridingTitleInlineContent: nil)) + XCTAssertEqual(firstParagraph.inlineContent[1], RenderInlineContent.reference(identifier: expectedReferenceIdentifier, isActive: true, overridingTitle: nil, overridingTitleInlineContent: nil)) let linkReference = translator.linkReferences[expectedReferenceIdentifier.identifier] XCTAssertNotNil(linkReference, "Link reference should have been collected by translator.") @@ -94,13 +94,13 @@ public class ExternalLinkTitleTests: XCTestCase { let (translator, content) = try getTranslatorAndBlockContentForMarkup(markupSource) - guard case let .paragraph(paragraphContent) = content[1] else { + guard case let .paragraph(firstParagraph) = content[1] else { XCTFail("Unexpected render tree.") return } let expectedReferenceIdentifier = RenderReferenceIdentifier.init(forExternalLink: "https://www.example.com") - XCTAssertEqual(paragraphContent[1], RenderInlineContent.reference(identifier: expectedReferenceIdentifier, isActive: true, overridingTitle: nil, overridingTitleInlineContent: nil)) + XCTAssertEqual(firstParagraph.inlineContent[1], RenderInlineContent.reference(identifier: expectedReferenceIdentifier, isActive: true, overridingTitle: nil, overridingTitleInlineContent: nil)) let linkReference = translator.linkReferences[expectedReferenceIdentifier.identifier] XCTAssertNotNil(linkReference, "Link reference should have been collected by translator.") @@ -121,13 +121,13 @@ public class ExternalLinkTitleTests: XCTestCase { let (translator, content) = try getTranslatorAndBlockContentForMarkup(markupSource) - guard case let .paragraph(paragraphContent) = content[1] else { + guard case let .paragraph(firstParagraph) = content[1] else { XCTFail("Unexpected render tree.") return } let expectedReferenceIdentifier = RenderReferenceIdentifier.init(forExternalLink: "https://www.example.com") - XCTAssertEqual(paragraphContent[1], RenderInlineContent.reference(identifier: expectedReferenceIdentifier, isActive: true, overridingTitle: nil, overridingTitleInlineContent: nil)) + XCTAssertEqual(firstParagraph.inlineContent[1], RenderInlineContent.reference(identifier: expectedReferenceIdentifier, isActive: true, overridingTitle: nil, overridingTitleInlineContent: nil)) let linkReference = translator.linkReferences[expectedReferenceIdentifier.identifier] XCTAssertNotNil(linkReference, "Link reference should have been collected by translator.") @@ -148,13 +148,13 @@ public class ExternalLinkTitleTests: XCTestCase { let (translator, content) = try getTranslatorAndBlockContentForMarkup(markupSource) - guard case let .paragraph(paragraphContent) = content[1] else { + guard case let .paragraph(firstParagraph) = content[1] else { XCTFail("Unexpected render tree.") return } let expectedReferenceIdentifier = RenderReferenceIdentifier.init(forExternalLink: "https://www.example.com") - XCTAssertEqual(paragraphContent[1], RenderInlineContent.reference(identifier: expectedReferenceIdentifier, isActive: true, overridingTitle: nil, overridingTitleInlineContent: nil)) + XCTAssertEqual(firstParagraph.inlineContent[1], RenderInlineContent.reference(identifier: expectedReferenceIdentifier, isActive: true, overridingTitle: nil, overridingTitleInlineContent: nil)) let linkReference = translator.linkReferences[expectedReferenceIdentifier.identifier] XCTAssertNotNil(linkReference, "Link reference should have been collected by translator.") @@ -184,10 +184,11 @@ public class ExternalLinkTitleTests: XCTestCase { let (translator, content) = try getTranslatorAndBlockContentForMarkup(markupSource) - guard case let .paragraph(paragraphContent) = content[1] else { + guard case let .paragraph(firstParagraph) = content[1] else { XCTFail("Unexpected render tree.") return } + let paragraphContent = firstParagraph.inlineContent let expectedReferenceIdentifier = RenderReferenceIdentifier.init(forExternalLink: "https://www.example.com") XCTAssertEqual(paragraphContent[1], RenderInlineContent.reference(identifier: expectedReferenceIdentifier, isActive: true, overridingTitle: nil, overridingTitleInlineContent: nil)) diff --git a/Tests/SwiftDocCTests/Rendering/IntroRenderSectionTests.swift b/Tests/SwiftDocCTests/Rendering/IntroRenderSectionTests.swift index 20daaa52c3..2261c59af5 100644 --- a/Tests/SwiftDocCTests/Rendering/IntroRenderSectionTests.swift +++ b/Tests/SwiftDocCTests/Rendering/IntroRenderSectionTests.swift @@ -58,7 +58,7 @@ class IntroRenderSectionTests: XCTestCase { overridingTitle: "Get started", overridingTitleInlineContent: [.text("Get started")] ) - intro.content = [.paragraph(inlineContent: [.text("This is the intro.")])] + intro.content = [.paragraph(.init(inlineContent: [.text("This is the intro.")]))] intro.image = .init("intro.png") XCTAssertEqual( diff --git a/Tests/SwiftDocCTests/Rendering/RESTExampleRenderSectionTests.swift b/Tests/SwiftDocCTests/Rendering/RESTExampleRenderSectionTests.swift index 941d7210ac..c245938650 100644 --- a/Tests/SwiftDocCTests/Rendering/RESTExampleRenderSectionTests.swift +++ b/Tests/SwiftDocCTests/Rendering/RESTExampleRenderSectionTests.swift @@ -33,14 +33,14 @@ class RESTExampleRenderSectionTests: XCTestCase { """.data(using: .utf8)! let content = try JSONDecoder().decode(RenderBlockContent.self, from: jsonData) - guard case .dictionaryExample(summary: nil, example: let example) = content else { + guard case .dictionaryExample(let e) = content, e.summary == nil else { XCTFail("Unexpected type of RenderBlockContent. Expected a 'dictionaryExample'.") return } - XCTAssertEqual(example.type, nil, "The `type` is optional in the specification and there's no value to decode in this test.") - XCTAssertEqual(example.syntax, nil, "The `syntax` is optional in the specification and there's no value to decode in this test.") - XCTAssertEqual(example.content, [ + XCTAssertEqual(e.example.type, nil, "The `type` is optional in the specification and there's no value to decode in this test.") + XCTAssertEqual(e.example.syntax, nil, "The `syntax` is optional in the specification and there's no value to decode in this test.") + XCTAssertEqual(e.example.content, [ CodeExample.Code(collapsible: false, code: ["lines of code", "goes here..."]), ]) } @@ -54,12 +54,13 @@ class RESTExampleRenderSectionTests: XCTestCase { let node = try JSONDecoder().decode(RenderNode.self, from: jsonData) guard let section = node.primaryContentSections[0] as? ContentRenderSection, - case .dictionaryExample(summary: nil, example: let example) = section.content[3] + case .dictionaryExample(let e) = section.content[3], + e.summary == nil else { XCTFail("Unexpected type of RenderBlockContent. Expected a 'dictionaryExample'.") return } - XCTAssertEqual(example.type, nil, "The `type` is optional in the specification and there's no value to decode in this test.") + XCTAssertEqual(e.example.type, nil, "The `type` is optional in the specification and there's no value to decode in this test.") } } diff --git a/Tests/SwiftDocCTests/Rendering/RESTSymbolsTests.swift b/Tests/SwiftDocCTests/Rendering/RESTSymbolsTests.swift index 23bd4fe644..4ce79b6bf8 100644 --- a/Tests/SwiftDocCTests/Rendering/RESTSymbolsTests.swift +++ b/Tests/SwiftDocCTests/Rendering/RESTSymbolsTests.swift @@ -22,8 +22,8 @@ fileprivate extension Array where Element == RenderBlockContent { }) .flatMap { block -> String? in switch block { - case .paragraph(inlineContent: let inline): - switch inline.first { + case .paragraph(let p): + switch p.inlineContent.first { case .some(.text(let string)): return string default: return nil } @@ -198,23 +198,23 @@ class RESTSymbolsTests: XCTestCase { return } - if case RenderBlockContent.endpointExample(let maybeSummary, let request, let response) = example { - XCTAssertNotNil(maybeSummary) - if case RenderBlockContent.paragraph(inlineContent: let summaryContent)? = maybeSummary?.first { - XCTAssertEqual(summaryContent, [RenderInlineContent.text("The summary of this endpoint example.")]) + if case RenderBlockContent.endpointExample(let e) = example { + XCTAssertNotNil(e.summary) + if case RenderBlockContent.paragraph(let summary)? = e.summary?.first { + XCTAssertEqual(summary.inlineContent, [RenderInlineContent.text("The summary of this endpoint example.")]) } else { XCTFail("Summary paragraph not found.") } - XCTAssertEqual(request.type, "file") - XCTAssertEqual(request.syntax, "http") - XCTAssertEqual(request.content.first?.collapsible, false) - XCTAssertEqual(request.content.first?.code.joined(), "Request content") + XCTAssertEqual(e.request.type, "file") + XCTAssertEqual(e.request.syntax, "http") + XCTAssertEqual(e.request.content.first?.collapsible, false) + XCTAssertEqual(e.request.content.first?.code.joined(), "Request content") - XCTAssertEqual(response.type, "file") - XCTAssertEqual(response.syntax, "json") - XCTAssertEqual(response.content.first?.collapsible, true) - XCTAssertEqual(response.content.first?.code.joined(), "Response content") + XCTAssertEqual(e.response.type, "file") + XCTAssertEqual(e.response.syntax, "json") + XCTAssertEqual(e.response.content.first?.collapsible, true) + XCTAssertEqual(e.response.content.first?.code.joined(), "Response content") } AssertRoundtrip(for: symbol) diff --git a/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorSymbolVariantsTests.swift b/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorSymbolVariantsTests.swift index c62892c489..69dff91098 100644 --- a/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorSymbolVariantsTests.swift +++ b/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorSymbolVariantsTests.swift @@ -434,8 +434,8 @@ class RenderNodeTranslatorSymbolVariantsTests: XCTestCase { XCTAssertEqual( returnsSection.content, [ - .heading(level: 2, text: "Return Value", anchor: "return-value"), - .paragraph(inlineContent: [.text("Swift Returns Section")]) + .heading(.init(level: 2, text: "Return Value", anchor: "return-value")), + .paragraph(.init(inlineContent: [.text("Swift Returns Section")])) ] ) }, @@ -444,8 +444,8 @@ class RenderNodeTranslatorSymbolVariantsTests: XCTestCase { XCTAssertEqual( returnsSection.content, [ - .heading(level: 2, text: "Return Value", anchor: "return-value"), - .paragraph(inlineContent: [.text("Objective-C Returns Section")]) + .heading(.init(level: 2, text: "Return Value", anchor: "return-value")), + .paragraph(.init(inlineContent: [.text("Objective-C Returns Section")])) ] ) } @@ -523,8 +523,8 @@ class RenderNodeTranslatorSymbolVariantsTests: XCTestCase { XCTAssertEqual( discussionSection.content, [ - .heading(level: 2, text: "Overview", anchor: "overview"), - .paragraph(inlineContent: [.text("Swift Discussion")]) + .heading(.init(level: 2, text: "Overview", anchor: "overview")), + .paragraph(.init(inlineContent: [.text("Swift Discussion")])) ] ) }, @@ -534,8 +534,8 @@ class RenderNodeTranslatorSymbolVariantsTests: XCTestCase { XCTAssertEqual( discussionSection.content, [ - .heading(level: 2, text: "Overview", anchor: "overview"), - .paragraph(inlineContent: [.text("Objective-C Discussion")]) + .heading(.init(level: 2, text: "Overview", anchor: "overview")), + .paragraph(.init(inlineContent: [.text("Objective-C Discussion")])) ] ) } @@ -1056,13 +1056,13 @@ class RenderNodeTranslatorSymbolVariantsTests: XCTestCase { assertOriginalRenderNode: { renderNode in XCTAssertEqual( renderNode.deprecationSummary, - [.paragraph(inlineContent: [.text("Swift Deprecation Variant")])] + [.paragraph(.init(inlineContent: [.text("Swift Deprecation Variant")]))] ) }, assertAfterApplyingVariant: { renderNode in XCTAssertEqual( renderNode.deprecationSummary, - [.paragraph(inlineContent: [.text("Objective-C Deprecation Variant")])] + [.paragraph(.init(inlineContent: [.text("Objective-C Deprecation Variant")]))] ) } ) diff --git a/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift b/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift index 31b62f2a6f..3b2334439a 100644 --- a/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift +++ b/Tests/SwiftDocCTests/Rendering/RenderNodeTranslatorTests.swift @@ -41,7 +41,7 @@ class RenderNodeTranslatorTests: XCTestCase { guard let paragraph = discussion.content .compactMap({ block -> [RenderInlineContent]? in switch block { - case .paragraph(inlineContent: let children): return children + case .paragraph(let p): return p.inlineContent default: return nil } }) @@ -102,11 +102,11 @@ class RenderNodeTranslatorTests: XCTestCase { } XCTAssert(discussion.content.contains(where: { block in - if case .orderedList(items: let items) = block, - items.count == 3, - case .paragraph([.text("One ordered")])? = items[0].content.first, - case .paragraph([.text("Two ordered")])? = items[1].content.first, - case .paragraph([.text("Three ordered")])? = items[2].content.first + if case .orderedList(let l) = block, + l.items.count == 3, + l.items[0].content.first == .paragraph(.init(inlineContent: [.text("One ordered")])), + l.items[1].content.first == .paragraph(.init(inlineContent: [.text("Two ordered")])), + l.items[2].content.first == .paragraph(.init(inlineContent: [.text("Three ordered")])) { return true } else { @@ -115,11 +115,11 @@ class RenderNodeTranslatorTests: XCTestCase { })) XCTAssert(discussion.content.contains(where: { block in - if case .unorderedList(items: let items) = block, - items.count == 3, - case .paragraph([.text("One unordered")])? = items[0].content.first, - case .paragraph([.text("Two unordered")])? = items[1].content.first, - case .paragraph([.text("Three unordered")])? = items[2].content.first + if case .unorderedList(let l) = block, + l.items.count == 3, + l.items[0].content.first == .paragraph(.init(inlineContent: [.text("One unordered")])), + l.items[1].content.first == .paragraph(.init(inlineContent: [.text("Two unordered")])), + l.items[2].content.first == .paragraph(.init(inlineContent: [.text("Three unordered")])) { return true } else { @@ -143,8 +143,8 @@ class RenderNodeTranslatorTests: XCTestCase { XCTAssertEqual( myFunctionDiscussion.content, [ - RenderBlockContent.heading(level: 2, text: "Discussion", anchor: "discussion"), - RenderBlockContent.paragraph(inlineContent: [.text("This is the overview for myFunction.")]), + RenderBlockContent.heading(.init(level: 2, text: "Discussion", anchor: "discussion")), + RenderBlockContent.paragraph(.init(inlineContent: [.text("This is the overview for myFunction.")])), ] ) @@ -165,8 +165,8 @@ class RenderNodeTranslatorTests: XCTestCase { XCTAssertEqual( myClassDiscussion.content, [ - RenderBlockContent.heading(level: 2, text: "Overview", anchor: "overview"), - RenderBlockContent.paragraph(inlineContent: [.text("This is the overview for MyClass.")]), + RenderBlockContent.heading(.init(level: 2, text: "Overview", anchor: "overview")), + RenderBlockContent.paragraph(.init(inlineContent: [.text("This is the overview for MyClass.")])), ] ) } @@ -177,7 +177,7 @@ class RenderNodeTranslatorTests: XCTestCase { let section = ContentRenderSection(kind: .content, content: [], heading: "declaration") XCTAssertEqual("declaration", section.content.mapFirst(where: { element -> String? in switch element { - case .heading(_, _, let anchor): return anchor + case .heading(let h): return h.anchor default: return nil } })) @@ -188,7 +188,7 @@ class RenderNodeTranslatorTests: XCTestCase { let section = ContentRenderSection(kind: .content, content: [], heading: "DeclaratioN") XCTAssertEqual("declaration", section.content.mapFirst(where: { element -> String? in switch element { - case .heading(_, _, let anchor): return anchor + case .heading(let h): return h.anchor default: return nil } })) @@ -199,7 +199,7 @@ class RenderNodeTranslatorTests: XCTestCase { let section = ContentRenderSection(kind: .content, content: [], heading: "My Declaration") XCTAssertEqual("my-declaration", section.content.mapFirst(where: { element -> String? in switch element { - case .heading(_, _, let anchor): return anchor + case .heading(let h): return h.anchor default: return nil } })) @@ -886,12 +886,12 @@ class RenderNodeTranslatorTests: XCTestCase { let discussion = try XCTUnwrap(renderNode.primaryContentSections.first(where: { $0.kind == .content }) as? ContentRenderSection) let paragraph = try XCTUnwrap(discussion.content.last) - guard case let RenderBlockContent.paragraph(inlineContent: elements) = paragraph else { + guard case let RenderBlockContent.paragraph(p) = paragraph else { XCTFail("Unexpected discussion content.") return } - XCTAssertEqual(elements, [ + XCTAssertEqual(p.inlineContent, [ .text("This is a link to "), .text("doc:/documentation/SideKit/SideClass/Element/Protocol-Implementations"), .text("."), @@ -944,15 +944,15 @@ class RenderNodeTranslatorTests: XCTestCase { let renderNode = try XCTUnwrap(translator.visitArticle(article) as? RenderNode) let discussion = try XCTUnwrap(renderNode.primaryContentSections.first(where: { $0.kind == .content }) as? ContentRenderSection) - if case let .paragraph(elements) = discussion.content.dropFirst(2).first { - XCTAssertEqual(elements, [.text("Does a foo.")]) + if case let .paragraph(p) = discussion.content.dropFirst(2).first { + XCTAssertEqual(p.inlineContent, [.text("Does a foo.")]) } else { XCTFail("Unexpected content where snippet explanation should be.") } - if case let .codeListing(syntax, code, _) = discussion.content.dropFirst(3).first { - XCTAssertEqual(syntax, "swift") - XCTAssertEqual(code.joined(separator: "\n"), """ + if case let .codeListing(l) = discussion.content.dropFirst(3).first { + XCTAssertEqual(l.syntax, "swift") + XCTAssertEqual(l.code.joined(separator: "\n"), """ func foo() {} do { @@ -981,13 +981,13 @@ class RenderNodeTranslatorTests: XCTestCase { return true }) - guard case let .codeListing(syntax, code, _) = discussion.content[lastCodeListingIndex] else { + guard case let .codeListing(l) = discussion.content[lastCodeListingIndex] else { XCTFail("Missing snippet slice code block") return } - XCTAssertEqual(syntax, "swift") - XCTAssertEqual(code, ["func foo() {}"]) + XCTAssertEqual(l.syntax, "swift") + XCTAssertEqual(l.code, ["func foo() {}"]) } func testSnippetSliceTrimsIndentation() throws { @@ -1005,13 +1005,13 @@ class RenderNodeTranslatorTests: XCTestCase { return true }) - guard case let .codeListing(syntax, code, _) = discussion.content[lastCodeListingIndex] else { + guard case let .codeListing(l) = discussion.content[lastCodeListingIndex] else { XCTFail("Missing snippet slice code block") return } - XCTAssertEqual(syntax, "swift") - XCTAssertEqual(code, ["middle()"]) + XCTAssertEqual(l.syntax, "swift") + XCTAssertEqual(l.code, ["middle()"]) } } diff --git a/Tests/SwiftDocCTests/Rendering/SampleDownloadTests.swift b/Tests/SwiftDocCTests/Rendering/SampleDownloadTests.swift index e8ea4d8bf8..1b310d8887 100644 --- a/Tests/SwiftDocCTests/Rendering/SampleDownloadTests.swift +++ b/Tests/SwiftDocCTests/Rendering/SampleDownloadTests.swift @@ -65,12 +65,12 @@ class SampleDownloadTests: XCTestCase { XCTAssertEqual(section.count, 1) - guard case let .paragraph(content) = section.first else { + guard case let .paragraph(contentParagraph) = section.first else { XCTFail("Section is not a paragraph.") return } - let text = content.rawIndexableTextContent(references: symbol.references) + let text = contentParagraph.inlineContent.rawIndexableTextContent(references: symbol.references) XCTAssertEqual(text, "You can experiment with the code. Just use WiFi Access on your Mac to download WiFi access sample code.") } diff --git a/Tests/SwiftDocCTests/Rendering/SubscriptSuperscriptElementsTests.swift b/Tests/SwiftDocCTests/Rendering/SubscriptSuperscriptElementsTests.swift index e106a3e017..017e78edb4 100644 --- a/Tests/SwiftDocCTests/Rendering/SubscriptSuperscriptElementsTests.swift +++ b/Tests/SwiftDocCTests/Rendering/SubscriptSuperscriptElementsTests.swift @@ -27,8 +27,8 @@ class SubscriptSuperscriptElementsTests: XCTestCase { return } - guard case RenderBlockContent.paragraph(inlineContent: let content) = discussion.content[1], - content.count == 5 else { + guard case RenderBlockContent.paragraph(let contentParagraph) = discussion.content[1], + contentParagraph.inlineContent.count == 5 else { XCTFail("Didn't find a paragraph element in discussion") return } @@ -38,6 +38,6 @@ class SubscriptSuperscriptElementsTests: XCTestCase { RenderInlineContent.text(" and "), RenderInlineContent.superscript(inlineContent: [.text("sup")]), RenderInlineContent.text(" to render attributed text."), - ], content) + ], contentParagraph.inlineContent) } } diff --git a/Tests/SwiftDocCTests/Rendering/TableElementTests.swift b/Tests/SwiftDocCTests/Rendering/TableElementTests.swift index 5aa3a418d6..1df32a15d2 100644 --- a/Tests/SwiftDocCTests/Rendering/TableElementTests.swift +++ b/Tests/SwiftDocCTests/Rendering/TableElementTests.swift @@ -27,16 +27,16 @@ class TableElementTests: XCTestCase { return } - guard case RenderBlockContent.table(let header, let rows, let metadata) = discussion.content[1] else { + guard case RenderBlockContent.table(let t) = discussion.content[1] else { XCTFail("Didn't find a table element in discussion") return } - XCTAssertEqual(RenderBlockContent.HeaderType(rawValue: "row"), header) + XCTAssertEqual(RenderBlockContent.HeaderType(rawValue: "row"), t.header) XCTAssertEqual([RenderBlockContent.TableRow(cells: [ - [RenderBlockContent.paragraph(inlineContent: [RenderInlineContent.text("cell 1:1")])], - [RenderBlockContent.paragraph(inlineContent: [RenderInlineContent.text("cell 1:2")])], - ])], rows) - XCTAssertEqual(RenderContentMetadata(anchor: "anchor", title: "Figure 1", abstract: [RenderInlineContent.text("Tabulur data")]), metadata) + [RenderBlockContent.paragraph(.init(inlineContent: [RenderInlineContent.text("cell 1:1")]))], + [RenderBlockContent.paragraph(.init(inlineContent: [RenderInlineContent.text("cell 1:2")]))], + ])], t.rows) + XCTAssertEqual(RenderContentMetadata(anchor: "anchor", title: "Figure 1", abstract: [RenderInlineContent.text("Tabulur data")]), t.metadata) } } diff --git a/Tests/SwiftDocCTests/Rendering/TermListTests.swift b/Tests/SwiftDocCTests/Rendering/TermListTests.swift index 56b0afef91..7e1778de83 100644 --- a/Tests/SwiftDocCTests/Rendering/TermListTests.swift +++ b/Tests/SwiftDocCTests/Rendering/TermListTests.swift @@ -37,13 +37,13 @@ class TermListTests: XCTestCase { XCTFail("Discussion section didn't have expected number of contents") return } - guard case let .termList(items) = content.first, + guard case let .termList(l) = content.first, content.count == 1 else { XCTFail("Term list not decoded") fatalError() } - XCTAssertEqual(items.count, 4) + XCTAssertEqual(l.items.count, 4) } func testRenderingListWithAllTermListItems() throws { @@ -81,8 +81,8 @@ class TermListTests: XCTestCase { let renderedTermList = try XCTUnwrap(result.first) switch renderedTermList { - case .termList(let items): - XCTAssertEqual(items.count, 4) + case .termList(let l): + XCTAssertEqual(l.items.count, 4) default: XCTFail("Unexpected element") } @@ -134,26 +134,26 @@ class TermListTests: XCTestCase { let secondTermList = result[3] switch firstUnorderedList { - case .unorderedList(let items): - XCTAssertEqual(items.count, 1) + case .unorderedList(let l): + XCTAssertEqual(l.items.count, 1) default: XCTFail("Unexpected element") } switch firstTermList { - case .termList(let items): - XCTAssertEqual(items.count, 3) + case .termList(let l): + XCTAssertEqual(l.items.count, 3) default: XCTFail("Unexpected element") } switch secondUnorderedList { - case .unorderedList(let items): - XCTAssertEqual(items.count, 2) + case .unorderedList(let l): + XCTAssertEqual(l.items.count, 2) default: XCTFail("Unexpected element") } switch secondTermList { - case .termList(let items): - XCTAssertEqual(items.count, 2) + case .termList(let l): + XCTAssertEqual(l.items.count, 2) default: XCTFail("Unexpected element") } diff --git a/Tests/SwiftDocCTests/Utility/RenderBlockContentTextExtraction.swift b/Tests/SwiftDocCTests/Utility/RenderBlockContentTextExtraction.swift index ec58613ee8..c8fd1fe7a3 100644 --- a/Tests/SwiftDocCTests/Utility/RenderBlockContentTextExtraction.swift +++ b/Tests/SwiftDocCTests/Utility/RenderBlockContentTextExtraction.swift @@ -15,8 +15,8 @@ extension Sequence where Element == RenderBlockContent { var paragraphText: [String] { compactMap { block in switch block { - case .paragraph(inlineContent: let children): - switch children[0] { + case .paragraph(let p): + switch p.inlineContent[0] { case .text(let text): return text default: return nil }