Update from Hummingbird Project Template (#58)

* Update from hummingbird-project-template 572d468b2cabeca286314c5a35196bd42445c8ef

* run swift-format

* Remove .swiftformat

---------

Co-authored-by: adam-fowler <adam-fowler@users.noreply.github.com>
Co-authored-by: Adam Fowler <adamfowler71@gmail.com>
This commit is contained in:
hummingbird-automation[bot]
2024-11-28 07:31:09 +00:00
committed by GitHub
parent 8c5c8ead74
commit ec4ef9aa04
21 changed files with 663 additions and 430 deletions

View File

@@ -17,11 +17,15 @@ import XCTest
final class ErrorTests: XCTestCase {
func testSectionCloseNameIncorrect() {
XCTAssertThrowsError(try MustacheTemplate(string: """
{{#test}}
{{.}}
{{/test2}}
""")) { error in
XCTAssertThrowsError(
try MustacheTemplate(
string: """
{{#test}}
{{.}}
{{/test2}}
"""
)
) { error in
switch error {
case let error as MustacheTemplate.ParserError:
XCTAssertEqual(error.error as? MustacheTemplate.Error, .sectionCloseNameIncorrect)
@@ -36,11 +40,15 @@ final class ErrorTests: XCTestCase {
}
func testUnfinishedName() {
XCTAssertThrowsError(try MustacheTemplate(string: """
{{#test}}
{{name}
{{/test2}}
""")) { error in
XCTAssertThrowsError(
try MustacheTemplate(
string: """
{{#test}}
{{name}
{{/test2}}
"""
)
) { error in
switch error {
case let error as MustacheTemplate.ParserError:
XCTAssertEqual(error.error as? MustacheTemplate.Error, .unfinishedName)
@@ -55,10 +63,14 @@ final class ErrorTests: XCTestCase {
}
func testExpectedSectionEnd() {
XCTAssertThrowsError(try MustacheTemplate(string: """
{{#test}}
{{.}}
""")) { error in
XCTAssertThrowsError(
try MustacheTemplate(
string: """
{{#test}}
{{.}}
"""
)
) { error in
switch error {
case let error as MustacheTemplate.ParserError:
XCTAssertEqual(error.error as? MustacheTemplate.Error, .expectedSectionEnd)
@@ -73,11 +85,15 @@ final class ErrorTests: XCTestCase {
}
func testInvalidSetDelimiter() {
XCTAssertThrowsError(try MustacheTemplate(string: """
{{=<% %>=}}
<%.%>
<%={{}}=%>
""")) { error in
XCTAssertThrowsError(
try MustacheTemplate(
string: """
{{=<% %>=}}
<%.%>
<%={{}}=%>
"""
)
) { error in
switch error {
case let error as MustacheTemplate.ParserError:
XCTAssertEqual(error.error as? MustacheTemplate.Error, .invalidSetDelimiter)

View File

@@ -12,9 +12,10 @@
//
//===----------------------------------------------------------------------===//
@testable import Mustache
import XCTest
@testable import Mustache
final class LibraryTests: XCTestCase {
func testDirectoryLoad() async throws {
let fs = FileManager()
@@ -54,11 +55,13 @@ final class LibraryTests: XCTestCase {
let mustache = Data("<test>{{#value}}<value>{{.}}</value>{{/value}}</test>".utf8)
try mustache.write(to: URL(fileURLWithPath: "templates/test.mustache"))
defer { XCTAssertNoThrow(try fs.removeItem(atPath: "templates/test.mustache")) }
let mustache2 = Data("""
{{#test}}
{{{name}}
{{/test2}}
""".utf8)
let mustache2 = Data(
"""
{{#test}}
{{{name}}
{{/test2}}
""".utf8
)
try mustache2.write(to: URL(fileURLWithPath: "templates/error.mustache"))
defer { XCTAssertNoThrow(try fs.removeItem(atPath: "templates/error.mustache")) }

View File

@@ -12,120 +12,156 @@
//
//===----------------------------------------------------------------------===//
@testable import Mustache
import XCTest
@testable import Mustache
final class PartialTests: XCTestCase {
/// Testing partials
func testMustacheManualExample9() throws {
let template = try MustacheTemplate(string: """
<h2>Names</h2>
{{#names}}
{{> user}}
{{/names}}
""")
let template2 = try MustacheTemplate(string: """
<strong>{{.}}</strong>
let template = try MustacheTemplate(
string: """
<h2>Names</h2>
{{#names}}
{{> user}}
{{/names}}
"""
)
let template2 = try MustacheTemplate(
string: """
<strong>{{.}}</strong>
""")
"""
)
let library = MustacheLibrary(templates: ["base": template, "user": template2])
let object: [String: Any] = ["names": ["john", "adam", "claire"]]
XCTAssertEqual(library.render(object, withTemplate: "base"), """
<h2>Names</h2>
<strong>john</strong>
<strong>adam</strong>
<strong>claire</strong>
XCTAssertEqual(
library.render(object, withTemplate: "base"),
"""
<h2>Names</h2>
<strong>john</strong>
<strong>adam</strong>
<strong>claire</strong>
""")
"""
)
}
/// Test where last line of partial generates no content. It should not add a
/// tab either
func testPartialEmptyLineTabbing() throws {
let template = try MustacheTemplate(string: """
<h2>Names</h2>
{{#names}}
{{> user}}
{{/names}}
Text after
let template = try MustacheTemplate(
string: """
<h2>Names</h2>
{{#names}}
{{> user}}
{{/names}}
Text after
""")
let template2 = try MustacheTemplate(string: """
{{^empty(.)}}
<strong>{{.}}</strong>
{{/empty(.)}}
{{#empty(.)}}
<strong>empty</strong>
{{/empty(.)}}
"""
)
let template2 = try MustacheTemplate(
string: """
{{^empty(.)}}
<strong>{{.}}</strong>
{{/empty(.)}}
{{#empty(.)}}
<strong>empty</strong>
{{/empty(.)}}
""")
"""
)
var library = MustacheLibrary()
library.register(template, named: "base")
library.register(template2, named: "user")
let object: [String: Any] = ["names": ["john", "adam", "claire"]]
XCTAssertEqual(library.render(object, withTemplate: "base"), """
<h2>Names</h2>
<strong>john</strong>
<strong>adam</strong>
<strong>claire</strong>
Text after
XCTAssertEqual(
library.render(object, withTemplate: "base"),
"""
<h2>Names</h2>
<strong>john</strong>
<strong>adam</strong>
<strong>claire</strong>
Text after
""")
"""
)
}
func testTrailingNewLines() throws {
let template1 = try MustacheTemplate(string: """
{{> withNewLine }}
>> {{> withNewLine }}
[ {{> withNewLine }} ]
""")
let template2 = try MustacheTemplate(string: """
{{> withoutNewLine }}
>> {{> withoutNewLine }}
[ {{> withoutNewLine }} ]
""")
let withNewLine = try MustacheTemplate(string: """
{{#things}}{{.}}, {{/things}}
let template1 = try MustacheTemplate(
string: """
{{> withNewLine }}
>> {{> withNewLine }}
[ {{> withNewLine }} ]
"""
)
let template2 = try MustacheTemplate(
string: """
{{> withoutNewLine }}
>> {{> withoutNewLine }}
[ {{> withoutNewLine }} ]
"""
)
let withNewLine = try MustacheTemplate(
string: """
{{#things}}{{.}}, {{/things}}
""")
"""
)
let withoutNewLine = try MustacheTemplate(string: "{{#things}}{{.}}, {{/things}}")
let library = MustacheLibrary(templates: ["base1": template1, "base2": template2, "withNewLine": withNewLine, "withoutNewLine": withoutNewLine])
let library = MustacheLibrary(templates: [
"base1": template1, "base2": template2, "withNewLine": withNewLine, "withoutNewLine": withoutNewLine,
])
let object = ["things": [1, 2, 3, 4, 5]]
XCTAssertEqual(library.render(object, withTemplate: "base1"), """
1, 2, 3, 4, 5,
>> 1, 2, 3, 4, 5,
XCTAssertEqual(
library.render(object, withTemplate: "base1"),
"""
1, 2, 3, 4, 5,
>> 1, 2, 3, 4, 5,
[ 1, 2, 3, 4, 5,
]
""")
XCTAssertEqual(library.render(object, withTemplate: "base2"), """
1, 2, 3, 4, 5, >> 1, 2, 3, 4, 5,
[ 1, 2, 3, 4, 5, ]
""")
[ 1, 2, 3, 4, 5,
]
"""
)
XCTAssertEqual(
library.render(object, withTemplate: "base2"),
"""
1, 2, 3, 4, 5, >> 1, 2, 3, 4, 5,
[ 1, 2, 3, 4, 5, ]
"""
)
}
/// Testing dynamic partials
func testDynamicPartials() throws {
let template = try MustacheTemplate(string: """
<h2>Names</h2>
{{partial}}
""")
let template2 = try MustacheTemplate(string: """
{{#names}}
<strong>{{.}}</strong>
{{/names}}
""")
let template = try MustacheTemplate(
string: """
<h2>Names</h2>
{{partial}}
"""
)
let template2 = try MustacheTemplate(
string: """
{{#names}}
<strong>{{.}}</strong>
{{/names}}
"""
)
let library = MustacheLibrary(templates: ["base": template])
let object: [String: Any] = ["names": ["john", "adam", "claire"], "partial": template2]
XCTAssertEqual(library.render(object, withTemplate: "base"), """
<h2>Names</h2>
<strong>john</strong>
<strong>adam</strong>
<strong>claire</strong>
XCTAssertEqual(
library.render(object, withTemplate: "base"),
"""
<h2>Names</h2>
<strong>john</strong>
<strong>adam</strong>
<strong>claire</strong>
""")
"""
)
}
/// test inheritance
@@ -163,15 +199,18 @@ final class PartialTests: XCTestCase {
""",
named: "mypage"
)
XCTAssertEqual(library.render({}, withTemplate: "mypage")!, """
<html>
<head>
<title>My page title</title>
</head>
<h1>Hello world</h1>
</html>
XCTAssertEqual(
library.render({}, withTemplate: "mypage")!,
"""
<html>
<head>
<title>My page title</title>
</head>
<h1>Hello world</h1>
</html>
""")
"""
)
}
func testInheritanceIndentation() throws {
@@ -194,11 +233,14 @@ final class PartialTests: XCTestCase {
""",
named: "template"
)
XCTAssertEqual(library.render({}, withTemplate: "template"), """
Hi,
one
two
XCTAssertEqual(
library.render({}, withTemplate: "template"),
"""
Hi,
one
two
""")
"""
)
}
}

View File

@@ -50,7 +50,8 @@ extension AnyDecodable {
self.init(dictionary.mapValues { $0.value })
} else {
throw DecodingError.dataCorruptedError(
in: container, debugDescription: "AnyDecodable value cannot be decoded"
in: container,
debugDescription: "AnyDecodable value cannot be decoded"
)
}
}
@@ -102,7 +103,8 @@ final class MustacheSpecTests: XCTestCase {
\(result ?? "nil")
expected:
\(test.expected)
""")
"""
)
}
}
}
@@ -113,7 +115,8 @@ final class MustacheSpecTests: XCTestCase {
func testSpec(name: String, ignoring: [String] = []) async throws {
let url = URL(
string: "https://raw.githubusercontent.com/mustache/spec/master/specs/\(name).json")!
string: "https://raw.githubusercontent.com/mustache/spec/master/specs/\(name).json"
)!
try await testSpec(url: url, ignoring: ignoring)
}
@@ -135,7 +138,8 @@ final class MustacheSpecTests: XCTestCase {
func testSpec(name: String, only: [String]) async throws {
let url = URL(
string: "https://raw.githubusercontent.com/mustache/spec/master/specs/\(name).json")!
string: "https://raw.githubusercontent.com/mustache/spec/master/specs/\(name).json"
)!
try await testSpec(url: url, only: only)
}
@@ -161,7 +165,12 @@ final class MustacheSpecTests: XCTestCase {
"Interpolation": MustacheLambda { "world" },
"Interpolation - Expansion": MustacheLambda { "{{planet}}" },
"Interpolation - Alternate Delimiters": MustacheLambda { "|planet| => {{planet}}" },
"Interpolation - Multiple Calls": MustacheLambda { return MustacheLambda { g += 1; return g }},
"Interpolation - Multiple Calls": MustacheLambda {
return MustacheLambda {
g += 1
return g
}
},
"Escaping": MustacheLambda { ">" },
"Section": MustacheLambda { text in text == "{{x}}" ? "yes" : "no" },
"Section - Expansion": MustacheLambda { text in text + "{{planet}}" + text },

View File

@@ -12,9 +12,10 @@
//
//===----------------------------------------------------------------------===//
@testable import Mustache
import XCTest
@testable import Mustache
final class TemplateParserTests: XCTestCase {
func testText() throws {
let template = try MustacheTemplate(string: "test template")

View File

@@ -141,81 +141,103 @@ final class TemplateRendererTests: XCTestCase {
/// variables
func testMustacheManualVariables() throws {
let template = try MustacheTemplate(string: """
Hello {{name}}
You have just won {{value}} dollars!
{{#in_ca}}
Well, {{taxed_value}} dollars, after taxes.
{{/in_ca}}
""")
let template = try MustacheTemplate(
string: """
Hello {{name}}
You have just won {{value}} dollars!
{{#in_ca}}
Well, {{taxed_value}} dollars, after taxes.
{{/in_ca}}
"""
)
let object: [String: Any] = ["name": "Chris", "value": 10000, "taxed_value": 10000 - (10000 * 0.4), "in_ca": true]
XCTAssertEqual(template.render(object), """
Hello Chris
You have just won 10000 dollars!
Well, 6000.0 dollars, after taxes.
XCTAssertEqual(
template.render(object),
"""
Hello Chris
You have just won 10000 dollars!
Well, 6000.0 dollars, after taxes.
""")
"""
)
}
/// test escaped and unescaped text
func testMustacheManualEscapedText() throws {
let template = try MustacheTemplate(string: """
*{{name}}
*{{age}}
*{{company}}
*{{{company}}}
""")
let template = try MustacheTemplate(
string: """
*{{name}}
*{{age}}
*{{company}}
*{{{company}}}
"""
)
let object: [String: Any] = ["name": "Chris", "company": "<b>GitHub</b>"]
XCTAssertEqual(template.render(object), """
*Chris
*
*&lt;b&gt;GitHub&lt;/b&gt;
*<b>GitHub</b>
""")
XCTAssertEqual(
template.render(object),
"""
*Chris
*
*&lt;b&gt;GitHub&lt;/b&gt;
*<b>GitHub</b>
"""
)
}
/// test dotted names
func test_MustacheManualDottedNames() throws {
let template = try MustacheTemplate(string: """
* {{client.name}}
* {{age}}
* {{client.company.name}}
* {{{company.name}}}
""")
let template = try MustacheTemplate(
string: """
* {{client.name}}
* {{age}}
* {{client.company.name}}
* {{{company.name}}}
"""
)
let object: [String: Any] = [
"client": (
name: "Chris & Friends",
age: 50
),
"company": [
"name": "<b>GitHub</b>",
"name": "<b>GitHub</b>"
],
]
XCTAssertEqual(template.render(object), """
* Chris &amp; Friends
*
*
* <b>GitHub</b>
""")
XCTAssertEqual(
template.render(object),
"""
* Chris &amp; Friends
*
*
* <b>GitHub</b>
"""
)
}
/// test implicit operator
func testMustacheManualImplicitOperator() throws {
let template = try MustacheTemplate(string: """
* {{.}}
""")
let template = try MustacheTemplate(
string: """
* {{.}}
"""
)
let object = "Hello!"
XCTAssertEqual(template.render(object), """
* Hello!
""")
XCTAssertEqual(
template.render(object),
"""
* Hello!
"""
)
}
/// test lambda
func test_MustacheManualLambda() throws {
let template = try MustacheTemplate(string: """
* {{time.hour}}
* {{today}}
""")
let template = try MustacheTemplate(
string: """
* {{time.hour}}
* {{today}}
"""
)
let object: [String: Any] = [
"year": 1970,
"month": 1,
@@ -231,113 +253,151 @@ final class TemplateRendererTests: XCTestCase {
return "{{year}}-{{month}}-{{day}}"
},
]
XCTAssertEqual(template.render(object), """
* 0
* 1970-1-1
""")
XCTAssertEqual(
template.render(object),
"""
* 0
* 1970-1-1
"""
)
}
/// test boolean
func testMustacheManualSectionFalse() throws {
let template = try MustacheTemplate(string: """
Shown.
{{#person}}
Never shown!
{{/person}}
""")
let template = try MustacheTemplate(
string: """
Shown.
{{#person}}
Never shown!
{{/person}}
"""
)
let object: [String: Any] = ["person": false]
XCTAssertEqual(template.render(object), """
Shown.
XCTAssertEqual(
template.render(object),
"""
Shown.
""")
"""
)
}
/// test non-empty lists
func testMustacheManualSectionList() throws {
let template = try MustacheTemplate(string: """
{{#repo}}
<b>{{name}}</b>
{{/repo}}
""")
let template = try MustacheTemplate(
string: """
{{#repo}}
<b>{{name}}</b>
{{/repo}}
"""
)
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
XCTAssertEqual(template.render(object), """
<b>resque</b>
<b>hub</b>
<b>rip</b>
XCTAssertEqual(
template.render(object),
"""
<b>resque</b>
<b>hub</b>
<b>rip</b>
""")
"""
)
}
/// test non-empty lists
func testMustacheManualSectionList2() throws {
let template = try MustacheTemplate(string: """
{{#repo}}
<b>{{.}}</b>
{{/repo}}
""")
let template = try MustacheTemplate(
string: """
{{#repo}}
<b>{{.}}</b>
{{/repo}}
"""
)
let object: [String: Any] = ["repo": ["resque", "hub", "rip"]]
XCTAssertEqual(template.render(object), """
<b>resque</b>
<b>hub</b>
<b>rip</b>
XCTAssertEqual(
template.render(object),
"""
<b>resque</b>
<b>hub</b>
<b>rip</b>
""")
"""
)
}
/// test lambdas
func testMustacheManualSectionLambda() throws {
let template = try MustacheTemplate(string: """
{{#wrapped}}{{name}} is awesome.{{/wrapped}}
""")
let template = try MustacheTemplate(
string: """
{{#wrapped}}{{name}} is awesome.{{/wrapped}}
"""
)
func wrapped(_ s: String) -> Any? {
return "<b>\(s)</b>"
"<b>\(s)</b>"
}
let object: [String: Any] = ["name": "Willy", "wrapped": MustacheLambda(wrapped)]
XCTAssertEqual(template.render(object), """
<b>Willy is awesome.</b>
""")
XCTAssertEqual(
template.render(object),
"""
<b>Willy is awesome.</b>
"""
)
}
/// test setting context object
func testMustacheManualContextObject() throws {
let template = try MustacheTemplate(string: """
{{#person?}}
Hi {{name}}!
{{/person?}}
""")
let template = try MustacheTemplate(
string: """
{{#person?}}
Hi {{name}}!
{{/person?}}
"""
)
let object: [String: Any] = ["person?": ["name": "Jon"]]
XCTAssertEqual(template.render(object), """
Hi Jon!
XCTAssertEqual(
template.render(object),
"""
Hi Jon!
""")
"""
)
}
/// test inverted sections
func testMustacheManualInvertedSection() throws {
let template = try MustacheTemplate(string: """
{{#repo}}
<b>{{name}}</b>
{{/repo}}
{{^repo}}
No repos :(
{{/repo}}
""")
let template = try MustacheTemplate(
string: """
{{#repo}}
<b>{{name}}</b>
{{/repo}}
{{^repo}}
No repos :(
{{/repo}}
"""
)
let object: [String: Any] = ["repo": []]
XCTAssertEqual(template.render(object), """
No repos :(
XCTAssertEqual(
template.render(object),
"""
No repos :(
""")
"""
)
}
/// test comments
func testMustacheManualComment() throws {
let template = try MustacheTemplate(string: """
<h1>Today{{! ignore me }}.</h1>
""")
let template = try MustacheTemplate(
string: """
<h1>Today{{! ignore me }}.</h1>
"""
)
let object: [String: Any] = ["repo": []]
XCTAssertEqual(template.render(object), """
<h1>Today.</h1>
""")
XCTAssertEqual(
template.render(object),
"""
<h1>Today.</h1>
"""
)
}
/// test dynamic names
@@ -357,18 +417,23 @@ final class TemplateRendererTests: XCTestCase {
/// test block with defaults
func testMustacheManualBlocksWithDefaults() throws {
let template = try MustacheTemplate(string: """
<h1>{{$title}}The News of Today{{/title}}</h1>
{{$body}}
<p>Nothing special happened.</p>
{{/body}}
let template = try MustacheTemplate(
string: """
<h1>{{$title}}The News of Today{{/title}}</h1>
{{$body}}
<p>Nothing special happened.</p>
{{/body}}
""")
XCTAssertEqual(template.render([]), """
<h1>The News of Today</h1>
<p>Nothing special happened.</p>
"""
)
XCTAssertEqual(
template.render([]),
"""
<h1>The News of Today</h1>
<p>Nothing special happened.</p>
""")
"""
)
}
func testMustacheManualParents() throws {
@@ -405,7 +470,7 @@ final class TemplateRendererTests: XCTestCase {
"headlines": [
"A pug's handler grew mustaches.",
"What an exciting day!",
],
]
]
XCTAssertEqual(
library.render(object, withTemplate: "main"),
@@ -474,11 +539,13 @@ final class TemplateRendererTests: XCTestCase {
}
func testPerformance() throws {
let template = try MustacheTemplate(string: """
{{#repo}}
<b>{{name}}</b>
{{/repo}}
""")
let template = try MustacheTemplate(
string: """
{{#repo}}
<b>{{name}}</b>
{{/repo}}
"""
)
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
let date = Date()
for _ in 1...10000 {

View File

@@ -17,177 +17,233 @@ import XCTest
final class TransformTests: XCTestCase {
func testLowercased() throws {
let template = try MustacheTemplate(string: """
{{ lowercased(name) }}
""")
let template = try MustacheTemplate(
string: """
{{ lowercased(name) }}
"""
)
let object: [String: Any] = ["name": "Test"]
XCTAssertEqual(template.render(object), "test")
}
func testUppercased() throws {
let template = try MustacheTemplate(string: """
{{ uppercased(name) }}
""")
let template = try MustacheTemplate(
string: """
{{ uppercased(name) }}
"""
)
let object: [String: Any] = ["name": "Test"]
XCTAssertEqual(template.render(object), "TEST")
}
func testNewline() throws {
let template = try MustacheTemplate(string: """
{{#repo}}
<b>{{name}}</b>
{{/repo}}
let template = try MustacheTemplate(
string: """
{{#repo}}
<b>{{name}}</b>
{{/repo}}
""")
"""
)
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
XCTAssertEqual(template.render(object), """
<b>resque</b>
<b>hub</b>
<b>rip</b>
XCTAssertEqual(
template.render(object),
"""
<b>resque</b>
<b>hub</b>
<b>rip</b>
""")
"""
)
}
func testFirstLast() throws {
let template = try MustacheTemplate(string: """
{{#repo}}
<b>{{#first()}}first: {{/first()}}{{#last()}}last: {{/last()}}{{ name }}</b>
{{/repo}}
let template = try MustacheTemplate(
string: """
{{#repo}}
<b>{{#first()}}first: {{/first()}}{{#last()}}last: {{/last()}}{{ name }}</b>
{{/repo}}
""")
"""
)
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
XCTAssertEqual(template.render(object), """
<b>first: resque</b>
<b>hub</b>
<b>last: rip</b>
XCTAssertEqual(
template.render(object),
"""
<b>first: resque</b>
<b>hub</b>
<b>last: rip</b>
""")
"""
)
}
func testIndex() throws {
let template = try MustacheTemplate(string: """
{{#repo}}
<b>{{#index()}}{{plusone(.)}}{{/index()}}) {{ name }}</b>
{{/repo}}
let template = try MustacheTemplate(
string: """
{{#repo}}
<b>{{#index()}}{{plusone(.)}}{{/index()}}) {{ name }}</b>
{{/repo}}
""")
"""
)
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
XCTAssertEqual(template.render(object), """
<b>1) resque</b>
<b>2) hub</b>
<b>3) rip</b>
XCTAssertEqual(
template.render(object),
"""
<b>1) resque</b>
<b>2) hub</b>
<b>3) rip</b>
""")
"""
)
}
func testDoubleSequenceTransformWorks() throws {
let template = try MustacheTemplate(string: """
{{#repo}}
{{count(reversed(numbers))}}
{{/repo}}
let template = try MustacheTemplate(
string: """
{{#repo}}
{{count(reversed(numbers))}}
{{/repo}}
""")
"""
)
let object: [String: Any] = ["repo": ["numbers": [1, 2, 3]]]
XCTAssertEqual(template.render(object), """
3
XCTAssertEqual(
template.render(object),
"""
3
""")
"""
)
}
func testMultipleTransformWorks() throws {
let template = try MustacheTemplate(string: """
{{#repo}}
{{minusone(plusone(last(reversed(numbers))))}}
{{/repo}}
let template = try MustacheTemplate(
string: """
{{#repo}}
{{minusone(plusone(last(reversed(numbers))))}}
{{/repo}}
""")
"""
)
let object: [String: Any] = ["repo": ["numbers": [5, 4, 3]]]
XCTAssertEqual(template.render(object), """
5
XCTAssertEqual(
template.render(object),
"""
5
""")
"""
)
}
func testNestedTransformWorks() throws {
let template = try MustacheTemplate(string: """
{{#repo}}
{{#uppercased(string)}}{{reversed(.)}}{{/uppercased(string)}}
{{/repo}}
let template = try MustacheTemplate(
string: """
{{#repo}}
{{#uppercased(string)}}{{reversed(.)}}{{/uppercased(string)}}
{{/repo}}
""")
"""
)
let object: [String: Any] = ["repo": ["string": "a123a"]]
XCTAssertEqual(template.render(object), """
A321A
XCTAssertEqual(
template.render(object),
"""
A321A
""")
"""
)
}
func testEvenOdd() throws {
let template = try MustacheTemplate(string: """
{{#repo}}
<b>{{index()}}) {{#even()}}even {{/even()}}{{#odd()}}odd {{/odd()}}{{ name }}</b>
{{/repo}}
let template = try MustacheTemplate(
string: """
{{#repo}}
<b>{{index()}}) {{#even()}}even {{/even()}}{{#odd()}}odd {{/odd()}}{{ name }}</b>
{{/repo}}
""")
"""
)
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
XCTAssertEqual(template.render(object), """
<b>0) even resque</b>
<b>1) odd hub</b>
<b>2) even rip</b>
XCTAssertEqual(
template.render(object),
"""
<b>0) even resque</b>
<b>1) odd hub</b>
<b>2) even rip</b>
""")
"""
)
}
func testReversed() throws {
let template = try MustacheTemplate(string: """
{{#reversed(repo)}}
<b>{{ name }}</b>
{{/reversed(repo)}}
let template = try MustacheTemplate(
string: """
{{#reversed(repo)}}
<b>{{ name }}</b>
{{/reversed(repo)}}
""")
"""
)
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
XCTAssertEqual(template.render(object), """
<b>rip</b>
<b>hub</b>
<b>resque</b>
XCTAssertEqual(
template.render(object),
"""
<b>rip</b>
<b>hub</b>
<b>resque</b>
""")
"""
)
}
func testArrayIndex() throws {
let template = try MustacheTemplate(string: """
{{#repo}}
<b>{{ index() }}) {{ name }}</b>
{{/repo}}
""")
let template = try MustacheTemplate(
string: """
{{#repo}}
<b>{{ index() }}) {{ name }}</b>
{{/repo}}
"""
)
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
XCTAssertEqual(template.render(object), """
<b>0) resque</b>
<b>1) hub</b>
<b>2) rip</b>
XCTAssertEqual(
template.render(object),
"""
<b>0) resque</b>
<b>1) hub</b>
<b>2) rip</b>
""")
"""
)
}
func testArraySorted() throws {
let template = try MustacheTemplate(string: """
{{#sorted(repo)}}
<b>{{ index() }}) {{ . }}</b>
{{/sorted(repo)}}
""")
let template = try MustacheTemplate(
string: """
{{#sorted(repo)}}
<b>{{ index() }}) {{ . }}</b>
{{/sorted(repo)}}
"""
)
let object: [String: Any] = ["repo": ["resque", "hub", "rip"]]
XCTAssertEqual(template.render(object), """
<b>0) hub</b>
<b>1) resque</b>
<b>2) rip</b>
XCTAssertEqual(
template.render(object),
"""
<b>0) hub</b>
<b>1) resque</b>
<b>2) rip</b>
""")
"""
)
}
func testDictionaryEmpty() throws {
let template = try MustacheTemplate(string: """
{{#empty(array)}}Array{{/empty(array)}}{{#empty(dictionary)}}Dictionary{{/empty(dictionary)}}
""")
let template = try MustacheTemplate(
string: """
{{#empty(array)}}Array{{/empty(array)}}{{#empty(dictionary)}}Dictionary{{/empty(dictionary)}}
"""
)
let object: [String: Any] = ["array": [], "dictionary": [:]]
XCTAssertEqual(template.render(object), "ArrayDictionary")
}
@@ -199,18 +255,22 @@ final class TransformTests: XCTestCase {
}
func testDictionaryEnumerated() throws {
let template = try MustacheTemplate(string: """
{{#enumerated(.)}}<b>{{ key }} = {{ value }}</b>{{/enumerated(.)}}
""")
let template = try MustacheTemplate(
string: """
{{#enumerated(.)}}<b>{{ key }} = {{ value }}</b>{{/enumerated(.)}}
"""
)
let object: [String: Any] = ["one": 1, "two": 2]
let result = template.render(object)
XCTAssertTrue(result == "<b>one = 1</b><b>two = 2</b>" || result == "<b>two = 2</b><b>one = 1</b>")
}
func testDictionarySortedByKey() throws {
let template = try MustacheTemplate(string: """
{{#sorted(.)}}<b>{{ key }} = {{ value }}</b>{{/sorted(.)}}
""")
let template = try MustacheTemplate(
string: """
{{#sorted(.)}}<b>{{ key }} = {{ value }}</b>{{/sorted(.)}}
"""
)
let object: [String: Any] = ["one": 1, "two": 2, "three": 3]
let result = template.render(object)
XCTAssertEqual(result, "<b>one = 1</b><b>three = 3</b><b>two = 2</b>")