Skip to content

Commit

Permalink
fix tag builder for Swift 5.8
Browse files Browse the repository at this point in the history
  • Loading branch information
tib committed Apr 1, 2023
1 parent 1fd007c commit f4fa5bc
Show file tree
Hide file tree
Showing 22 changed files with 642 additions and 568 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ open class Description: Tag {

open class Rss: Tag {

public init(@TagBuilder _ builder: () -> [Tag]) {
public init(@TagBuilder _ builder: () -> Tag) {
super.init(builder())
setAttributes([
.init(key: "version", value: "2.0"),
Expand Down
4 changes: 2 additions & 2 deletions Sources/SwiftHtml/Tags/Map.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
/// The `<map>` element contains a number of `<area>` elements, that defines the clickable areas in the image map.
open class Map: Tag {

public init(name: String, @TagBuilder _ builder: () -> [Tag]) {
super.init(builder())
public init(name: String, @TagBuilder _ builder: () -> Tag) {
super.init([builder()])
setAttributes([
.init(key: "name", value: name)
])
Expand Down
4 changes: 2 additions & 2 deletions Sources/SwiftRss/Rss.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
// https://validator.w3.org/feed/docs/rss2.html#ltttlgtSubelementOfLtchannelgt
open class Rss: Tag {

public init(@TagBuilder _ builder: () -> [Tag]) {
super.init(builder())
public init(@TagBuilder _ builder: () -> Tag) {
super.init([builder()])
setAttributes([
.init(key: "version", value: "2.0"),
// .init(key: "xmlns:atom", value: "http://www.w3.org/2005/Atom"),
Expand Down
4 changes: 2 additions & 2 deletions Sources/SwiftSgml/Tag.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ open class Tag {
}

/// initialize a new Tag with children using a builder
public convenience init(@TagBuilder _ builder: () -> [Tag]) {
self.init(builder())
public convenience init(@TagBuilder _ builder: () -> Tag) {
self.init([builder()])
}

// /// initialize a new Tag with children using an async throwing builder
Expand Down
34 changes: 11 additions & 23 deletions Sources/SwiftSgml/TagBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,28 @@
@resultBuilder
public enum TagBuilder {

public static func buildBlock(_ components: [Tag]...) -> [Tag] {
components.flatMap { $0 }
}

public static func buildBlock(_ components: [Tag]...) -> Tag {
let flat = components.flatMap { $0 }
if flat.count < 2, let first = flat.first {
return first
}
return GroupTag(flat)
GroupTag(components.flatMap { $0 })
}

public static func buildExpression(_ expression: [Tag]) -> [Tag] {
expression
public static func buildBlock(_ components: Tag...) -> Tag {
GroupTag(components)
}

public static func buildExpression(_ expression: Tag) -> [Tag] {
[expression]
public static func buildOptional(_ component: Tag?) -> Tag {
component ?? GroupTag()
}

public static func buildEither(first component: [Tag]) -> [Tag] {
public static func buildEither(first component: Tag) -> Tag {
component
}

public static func buildEither(second component: [Tag]) -> [Tag] {
public static func buildEither(second component: Tag) -> Tag {
component
}

public static func buildOptional(_ component: [Tag]?) -> [Tag] {
component ?? []
}

public static func buildArray(_ components: [[Tag]]) -> [Tag] {
components.flatMap { $0 }
public static func buildArray(_ components: [Tag]) -> Tag {
GroupTag(components)
}
}

4 changes: 2 additions & 2 deletions Sources/SwiftSitemap/SitemapIndex.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

open class SitemapIndex: Tag {

public init(@TagBuilder _ builder: () -> [Tag]) {
super.init(builder())
public init(@TagBuilder _ builder: () -> Tag) {
super.init([builder()])
setAttributes([
.init(key: "xmlns", value: "http://www.sitemaps.org/schemas/sitemap/0.9"),
])
Expand Down
4 changes: 2 additions & 2 deletions Sources/SwiftSitemap/UrlSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

open class UrlSet: Tag {

public init(@TagBuilder _ builder: () -> [Tag]) {
super.init(builder())
public init(@TagBuilder _ builder: () -> Tag) {
super.init([builder()])
setAttributes([
.init(key: "xmlns", value: "http://www.sitemaps.org/schemas/sitemap/0.9"),
])
Expand Down
120 changes: 62 additions & 58 deletions Tests/SwiftHtmlTests/SwiftHtmlTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import XCTest

extension Div {

convenience init(_ value: String, @TagBuilder _ builder: () -> [Tag]) {
convenience init(_ value: String, @TagBuilder _ builder: () -> Tag) {
self.init(builder())
self.setAttributes([
.init(key: "some-key", value: value)
Expand All @@ -19,7 +19,7 @@ extension Div {
}

final class SwiftHtmlTests: XCTestCase {

func testCustomInitWithAttribute() {
let doc = Document {
Div("some-value") {
Expand All @@ -30,15 +30,15 @@ final class SwiftHtmlTests: XCTestCase {
let html = DocumentRenderer(minify: true).render(doc)
XCTAssertEqual(#"<div some-key="some-value"><span>a</span><span>b</span></div>"#, html)
}

func testClassAttribute() {
let doc = Document {
Span("").class("a", "b", "", "b", "c")
}
let html = DocumentRenderer(minify: true).render(doc)
XCTAssertEqual(#"<span class="a b b c"></span>"#, html)
}

func testMultipleClasses() {
let doc = Document {
Span("")
Expand All @@ -48,7 +48,7 @@ final class SwiftHtmlTests: XCTestCase {
let html = DocumentRenderer(minify: true).render(doc)
XCTAssertEqual(#"<span class="d e f"></span>"#, html)
}

func testClassManipulation() {
let doc = Document {
Span("")
Expand All @@ -61,7 +61,7 @@ final class SwiftHtmlTests: XCTestCase {
let html = DocumentRenderer(minify: true).render(doc)
XCTAssertEqual(#"<span class="a f"></span>"#, html)
}

func testAddClass() {
let doc = Document {
Span("")
Expand All @@ -71,7 +71,7 @@ final class SwiftHtmlTests: XCTestCase {
let html = DocumentRenderer(minify: true).render(doc)
XCTAssertEqual(#"<span class="a b c d"></span>"#, html)
}

func testRemoveClass() {
let doc = Document {
Span("")
Expand All @@ -81,7 +81,7 @@ final class SwiftHtmlTests: XCTestCase {
let html = DocumentRenderer(minify: true).render(doc)
XCTAssertEqual(#"<span class="a c"></span>"#, html)
}

func testRemoveLastClass() {
let doc = Document {
Span("")
Expand All @@ -91,7 +91,7 @@ final class SwiftHtmlTests: XCTestCase {
let html = DocumentRenderer(minify: true).render(doc)
XCTAssertEqual(#"<span></span>"#, html)
}

func testToggleAddClass() {
let doc = Document {
Span("")
Expand All @@ -101,7 +101,7 @@ final class SwiftHtmlTests: XCTestCase {
let html = DocumentRenderer(minify: true).render(doc)
XCTAssertEqual(#"<span class="a b c d"></span>"#, html)
}

func testToggleRemoveClass() {
let doc = Document {
Span("")
Expand All @@ -111,7 +111,7 @@ final class SwiftHtmlTests: XCTestCase {
let html = DocumentRenderer(minify: true).render(doc)
XCTAssertEqual(#"<span class="a c"></span>"#, html)
}

func testSetEmptyStyle() {
let doc = Document {
Span("")
Expand All @@ -120,7 +120,7 @@ final class SwiftHtmlTests: XCTestCase {
let html = DocumentRenderer(minify: true).render(doc)
XCTAssertEqual(#"<span></span>"#, html)
}

func testTextTag() {
let doc = Document() {
P {
Expand All @@ -130,18 +130,20 @@ final class SwiftHtmlTests: XCTestCase {
}
}

XCTAssertEqual(DocumentRenderer().render(doc), """
<p>
<span>foo</span>
bar
<span>baz</span>
</p>
""")
let html = """
<p>
<span>foo</span>
bar
<span>baz</span>
</p>
"""

assert(doc: doc, html: html)
}

func testMultiGroupTagBuilderAndRenderer() {
let values: [String] = ["a", "b", "c"]

let doc = Document {
Div {
values.map { item -> Tag in
Expand All @@ -153,24 +155,25 @@ final class SwiftHtmlTests: XCTestCase {
}
}

XCTAssertEqual(DocumentRenderer().render(doc), """
<div>
<h1>a</h1>
<p>a</p>
<h1>b</h1>
<p>b</p>
<h1>c</h1>
<p>c</p>
</div>
""")
let html = """
<div>
<h1>a</h1>
<p>a</p>
<h1>b</h1>
<p>b</p>
<h1>c</h1>
<p>c</p>
</div>
"""
assert(doc: doc, html: html)
}

func testHtmlDocument() {
let doc = Document(.html) {
Html {
Head {
Title("Hello Swift DSL")

Meta().charset("utf-8")
Meta().name(.viewport).content("width=device-width, initial-scale=1")

Expand Down Expand Up @@ -204,30 +207,31 @@ final class SwiftHtmlTests: XCTestCase {
}
}

XCTAssertEqual(DocumentRenderer().render(doc), """
<!DOCTYPE html>
<html>
<head>
<title>Hello Swift DSL</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<main class="container">
<div>
<section>
<img src="./images/swift.png" alt="Swift Logo" title="Picture of the Swift Logo">
<h1 class="red">Lorem ipsum</h1>
<p class="green blue" spellcheck="false">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla pretium leo eu euismod porta.</p>
</section>
<a href="https://swift.org" target="_blank" download>Hello Swift HTML DSL!</a>
<abbr title="World Health Organization">WHO</abbr>
</div>
</main>
<script src="./javascript/main.js"></script>
</body>
</html>
""")
let html = """
<!DOCTYPE html>
<html>
<head>
<title>Hello Swift DSL</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<main class="container">
<div>
<section>
<img src="./images/swift.png" alt="Swift Logo" title="Picture of the Swift Logo">
<h1 class="red">Lorem ipsum</h1>
<p class="green blue" spellcheck="false">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla pretium leo eu euismod porta.</p>
</section>
<a href="https://swift.org" target="_blank" download>Hello Swift HTML DSL!</a>
<abbr title="World Health Organization">WHO</abbr>
</div>
</main>
<script src="./javascript/main.js"></script>
</body>
</html>
"""
assert(doc: doc, html: html)
}
}
Loading

0 comments on commit f4fa5bc

Please sign in to comment.