HBTemplate -> HBMustacheTemplate, escape characters
Add tests for mustache examples
This commit is contained in:
@@ -13,12 +13,12 @@ extension Dictionary: HBMustacheParent where Key == String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protocol HBSequence {
|
protocol HBSequence {
|
||||||
func renderSection(with template: HBTemplate) -> String
|
func renderSection(with template: HBMustacheTemplate) -> String
|
||||||
func renderInvertedSection(with template: HBTemplate) -> String
|
func renderInvertedSection(with template: HBMustacheTemplate) -> String
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Array: HBSequence {
|
extension Array: HBSequence {
|
||||||
func renderSection(with template: HBTemplate) -> String {
|
func renderSection(with template: HBMustacheTemplate) -> String {
|
||||||
var string = ""
|
var string = ""
|
||||||
for obj in self {
|
for obj in self {
|
||||||
string += template.render(obj)
|
string += template.render(obj)
|
||||||
@@ -26,7 +26,7 @@ extension Array: HBSequence {
|
|||||||
return string
|
return string
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderInvertedSection(with template: HBTemplate) -> String {
|
func renderInvertedSection(with template: HBMustacheTemplate) -> String {
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
return template.render(self)
|
return template.render(self)
|
||||||
}
|
}
|
||||||
@@ -35,7 +35,7 @@ extension Array: HBSequence {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension Dictionary: HBSequence {
|
extension Dictionary: HBSequence {
|
||||||
func renderSection(with template: HBTemplate) -> String {
|
func renderSection(with template: HBMustacheTemplate) -> String {
|
||||||
var string = ""
|
var string = ""
|
||||||
for obj in self {
|
for obj in self {
|
||||||
string += template.render(obj)
|
string += template.render(obj)
|
||||||
@@ -43,7 +43,7 @@ extension Dictionary: HBSequence {
|
|||||||
return string
|
return string
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderInvertedSection(with template: HBTemplate) -> String {
|
func renderInvertedSection(with template: HBMustacheTemplate) -> String {
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
return template.render(self)
|
return template.render(self)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
extension HBTemplate {
|
extension HBMustacheTemplate {
|
||||||
static func parse(_ string: String) throws -> [Token] {
|
static func parse(_ string: String) throws -> [Token] {
|
||||||
var parser = HBParser(string)
|
var parser = HBParser(string)
|
||||||
return try parse(&parser, sectionName: nil)
|
return try parse(&parser, sectionName: nil)
|
||||||
@@ -17,14 +17,20 @@ extension HBTemplate {
|
|||||||
case "#":
|
case "#":
|
||||||
parser.unsafeAdvance()
|
parser.unsafeAdvance()
|
||||||
let name = try parseSectionName(&parser)
|
let name = try parseSectionName(&parser)
|
||||||
|
if parser.current() == "\n" {
|
||||||
|
parser.unsafeAdvance()
|
||||||
|
}
|
||||||
let sectionTokens = try parse(&parser, sectionName: name)
|
let sectionTokens = try parse(&parser, sectionName: name)
|
||||||
tokens.append(.section(name, HBTemplate(sectionTokens)))
|
tokens.append(.section(name, HBMustacheTemplate(sectionTokens)))
|
||||||
|
|
||||||
case "^":
|
case "^":
|
||||||
parser.unsafeAdvance()
|
parser.unsafeAdvance()
|
||||||
let name = try parseSectionName(&parser)
|
let name = try parseSectionName(&parser)
|
||||||
|
if parser.current() == "\n" {
|
||||||
|
parser.unsafeAdvance()
|
||||||
|
}
|
||||||
let sectionTokens = try parse(&parser, sectionName: name)
|
let sectionTokens = try parse(&parser, sectionName: name)
|
||||||
tokens.append(.invertedSection(name, HBTemplate(sectionTokens)))
|
tokens.append(.invertedSection(name, HBMustacheTemplate(sectionTokens)))
|
||||||
|
|
||||||
case "/":
|
case "/":
|
||||||
parser.unsafeAdvance()
|
parser.unsafeAdvance()
|
||||||
@@ -32,13 +38,16 @@ extension HBTemplate {
|
|||||||
guard name == sectionName else {
|
guard name == sectionName else {
|
||||||
throw HBMustacheError.sectionCloseNameIncorrect
|
throw HBMustacheError.sectionCloseNameIncorrect
|
||||||
}
|
}
|
||||||
|
if parser.current() == "\n" {
|
||||||
|
parser.unsafeAdvance()
|
||||||
|
}
|
||||||
return tokens
|
return tokens
|
||||||
|
|
||||||
case "{":
|
case "{":
|
||||||
parser.unsafeAdvance()
|
parser.unsafeAdvance()
|
||||||
let name = try parseSectionName(&parser)
|
let name = try parseSectionName(&parser)
|
||||||
guard try parser.read("}") else { throw HBMustacheError.unfinishedSectionName }
|
guard try parser.read("}") else { throw HBMustacheError.unfinishedSectionName }
|
||||||
tokens.append(.variable(name))
|
tokens.append(.unescapedVariable(name))
|
||||||
|
|
||||||
case "!":
|
case "!":
|
||||||
parser.unsafeAdvance()
|
parser.unsafeAdvance()
|
||||||
@@ -67,5 +76,5 @@ extension HBTemplate {
|
|||||||
return text.string
|
return text.string
|
||||||
}
|
}
|
||||||
|
|
||||||
private static let sectionNameChars = Set<Unicode.Scalar>("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.")
|
private static let sectionNameChars = Set<Unicode.Scalar>("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ._?")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
extension HBTemplate {
|
extension HBMustacheTemplate {
|
||||||
public func render(_ object: Any) -> String {
|
public func render(_ object: Any) -> String {
|
||||||
var string = ""
|
var string = ""
|
||||||
for token in tokens {
|
for token in tokens {
|
||||||
@@ -7,48 +7,32 @@ extension HBTemplate {
|
|||||||
case .text(let text):
|
case .text(let text):
|
||||||
string += text
|
string += text
|
||||||
case .variable(let variable):
|
case .variable(let variable):
|
||||||
|
if let child = getChild(named: variable, from: object) {
|
||||||
|
string += encodedEscapedCharacters(String(describing: child))
|
||||||
|
}
|
||||||
|
case .unescapedVariable(let variable):
|
||||||
if let child = getChild(named: variable, from: object) {
|
if let child = getChild(named: variable, from: object) {
|
||||||
string += String(describing: child)
|
string += String(describing: child)
|
||||||
}
|
}
|
||||||
case .section(let variable, let template):
|
case .section(let variable, let template):
|
||||||
let child = getChild(named: variable, from: object)
|
let child = getChild(named: variable, from: object)
|
||||||
string += renderSection(child, with: template)
|
string += renderSection(child, parent: object, with: template)
|
||||||
|
|
||||||
case .invertedSection(let variable, let template):
|
case .invertedSection(let variable, let template):
|
||||||
let child = getChild(named: variable, from: object)
|
let child = getChild(named: variable, from: object)
|
||||||
string += renderInvertedSection(child, with: template)
|
string += renderInvertedSection(child, parent: object, with: template)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return string
|
return string
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderSection(_ object: Any?, with template: HBTemplate) -> String {
|
func renderSection(_ child: Any?, parent: Any, with template: HBMustacheTemplate) -> String {
|
||||||
switch object {
|
switch child {
|
||||||
case let array as HBSequence:
|
case let array as HBSequence:
|
||||||
return array.renderSection(with: template)
|
return array.renderSection(with: template)
|
||||||
case let bool as Bool:
|
case let bool as Bool:
|
||||||
return bool ? template.render(true) : ""
|
return bool ? template.render(parent) : ""
|
||||||
case let int as Int:
|
|
||||||
return int != 0 ? template.render(int) : ""
|
|
||||||
case let int as Int8:
|
|
||||||
return int != 0 ? template.render(int) : ""
|
|
||||||
case let int as Int16:
|
|
||||||
return int != 0 ? template.render(int) : ""
|
|
||||||
case let int as Int32:
|
|
||||||
return int != 0 ? template.render(int) : ""
|
|
||||||
case let int as Int64:
|
|
||||||
return int != 0 ? template.render(int) : ""
|
|
||||||
case let int as UInt:
|
|
||||||
return int != 0 ? template.render(int) : ""
|
|
||||||
case let int as UInt8:
|
|
||||||
return int != 0 ? template.render(int) : ""
|
|
||||||
case let int as UInt16:
|
|
||||||
return int != 0 ? template.render(int) : ""
|
|
||||||
case let int as UInt32:
|
|
||||||
return int != 0 ? template.render(int) : ""
|
|
||||||
case let int as UInt64:
|
|
||||||
return int != 0 ? template.render(int) : ""
|
|
||||||
case .some(let value):
|
case .some(let value):
|
||||||
return template.render(value)
|
return template.render(value)
|
||||||
case .none:
|
case .none:
|
||||||
@@ -56,36 +40,16 @@ extension HBTemplate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderInvertedSection(_ object: Any?, with template: HBTemplate) -> String {
|
func renderInvertedSection(_ child: Any?, parent: Any, with template: HBMustacheTemplate) -> String {
|
||||||
switch object {
|
switch child {
|
||||||
case let array as HBSequence:
|
case let array as HBSequence:
|
||||||
return array.renderInvertedSection(with: template)
|
return array.renderInvertedSection(with: template)
|
||||||
case let bool as Bool:
|
case let bool as Bool:
|
||||||
return bool ? "" : template.render(true)
|
return bool ? "" : template.render(parent)
|
||||||
case let int as Int:
|
|
||||||
return int == 0 ? template.render(int) : ""
|
|
||||||
case let int as Int8:
|
|
||||||
return int == 0 ? template.render(int) : ""
|
|
||||||
case let int as Int16:
|
|
||||||
return int == 0 ? template.render(int) : ""
|
|
||||||
case let int as Int32:
|
|
||||||
return int == 0 ? template.render(int) : ""
|
|
||||||
case let int as Int64:
|
|
||||||
return int == 0 ? template.render(int) : ""
|
|
||||||
case let int as UInt:
|
|
||||||
return int == 0 ? template.render(int) : ""
|
|
||||||
case let int as UInt8:
|
|
||||||
return int == 0 ? template.render(int) : ""
|
|
||||||
case let int as UInt16:
|
|
||||||
return int == 0 ? template.render(int) : ""
|
|
||||||
case let int as UInt32:
|
|
||||||
return int == 0 ? template.render(int) : ""
|
|
||||||
case let int as UInt64:
|
|
||||||
return int == 0 ? template.render(int) : ""
|
|
||||||
case .some:
|
case .some:
|
||||||
return ""
|
return ""
|
||||||
case .none:
|
case .none:
|
||||||
return template.render(Void())
|
return template.render(parent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,6 +72,24 @@ extension HBTemplate {
|
|||||||
let nameSplit = name.split(separator: ".").map { String($0) }
|
let nameSplit = name.split(separator: ".").map { String($0) }
|
||||||
return _getChild(named: nameSplit[...], from: object)
|
return _getChild(named: nameSplit[...], from: object)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static let escapedCharacters: [Character: String] = [
|
||||||
|
"<": "<",
|
||||||
|
">": ">",
|
||||||
|
"&": "&",
|
||||||
|
]
|
||||||
|
func encodedEscapedCharacters(_ string: String) -> String {
|
||||||
|
var newString = ""
|
||||||
|
newString.reserveCapacity(string.count)
|
||||||
|
for c in string {
|
||||||
|
if let replacement = Self.escapedCharacters[c] {
|
||||||
|
newString += replacement
|
||||||
|
} else {
|
||||||
|
newString.append(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newString
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func unwrap(_ any: Any) -> Any? {
|
func unwrap(_ any: Any) -> Any? {
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ enum HBMustacheError: Error {
|
|||||||
case expectedSectionEnd
|
case expectedSectionEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
public class HBTemplate {
|
public class HBMustacheTemplate {
|
||||||
public init(_ string: String) throws {
|
public init(string: String) throws {
|
||||||
self.tokens = try Self.parse(string)
|
self.tokens = try Self.parse(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17,8 +17,9 @@ public class HBTemplate {
|
|||||||
enum Token {
|
enum Token {
|
||||||
case text(String)
|
case text(String)
|
||||||
case variable(String)
|
case variable(String)
|
||||||
case section(String, HBTemplate)
|
case unescapedVariable(String)
|
||||||
case invertedSection(String, HBTemplate)
|
case section(String, HBMustacheTemplate)
|
||||||
|
case invertedSection(String, HBMustacheTemplate)
|
||||||
}
|
}
|
||||||
|
|
||||||
let tokens: [Token]
|
let tokens: [Token]
|
||||||
|
|||||||
@@ -3,39 +3,39 @@ import XCTest
|
|||||||
|
|
||||||
final class TemplateParserTests: XCTestCase {
|
final class TemplateParserTests: XCTestCase {
|
||||||
func testText() throws {
|
func testText() throws {
|
||||||
let template = try HBTemplate("test template")
|
let template = try HBMustacheTemplate(string: "test template")
|
||||||
XCTAssertEqual(template.tokens, [.text("test template")])
|
XCTAssertEqual(template.tokens, [.text("test template")])
|
||||||
}
|
}
|
||||||
|
|
||||||
func testVariable() throws {
|
func testVariable() throws {
|
||||||
let template = try HBTemplate("test {{variable}}")
|
let template = try HBMustacheTemplate(string: "test {{variable}}")
|
||||||
XCTAssertEqual(template.tokens, [.text("test "), .variable("variable")])
|
XCTAssertEqual(template.tokens, [.text("test "), .variable("variable")])
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSection() throws {
|
func testSection() throws {
|
||||||
let template = try HBTemplate("test {{#section}}text{{/section}}")
|
let template = try HBMustacheTemplate(string: "test {{#section}}text{{/section}}")
|
||||||
XCTAssertEqual(template.tokens, [.text("test "), .section("section", .init([.text("text")]))])
|
XCTAssertEqual(template.tokens, [.text("test "), .section("section", .init([.text("text")]))])
|
||||||
}
|
}
|
||||||
|
|
||||||
func testInvertedSection() throws {
|
func testInvertedSection() throws {
|
||||||
let template = try HBTemplate("test {{^section}}text{{/section}}")
|
let template = try HBMustacheTemplate(string: "test {{^section}}text{{/section}}")
|
||||||
XCTAssertEqual(template.tokens, [.text("test "), .invertedSection("section", .init([.text("text")]))])
|
XCTAssertEqual(template.tokens, [.text("test "), .invertedSection("section", .init([.text("text")]))])
|
||||||
}
|
}
|
||||||
|
|
||||||
func testComment() throws {
|
func testComment() throws {
|
||||||
let template = try HBTemplate("test {{!section}}")
|
let template = try HBMustacheTemplate(string: "test {{!section}}")
|
||||||
XCTAssertEqual(template.tokens, [.text("test ")])
|
XCTAssertEqual(template.tokens, [.text("test ")])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension HBTemplate: Equatable {
|
extension HBMustacheTemplate: Equatable {
|
||||||
public static func == (lhs: HBTemplate, rhs: HBTemplate) -> Bool {
|
public static func == (lhs: HBMustacheTemplate, rhs: HBMustacheTemplate) -> Bool {
|
||||||
lhs.tokens == rhs.tokens
|
lhs.tokens == rhs.tokens
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension HBTemplate.Token: Equatable {
|
extension HBMustacheTemplate.Token: Equatable {
|
||||||
public static func == (lhs: HBTemplate.Token, rhs: HBTemplate.Token) -> Bool {
|
public static func == (lhs: HBMustacheTemplate.Token, rhs: HBMustacheTemplate.Token) -> Bool {
|
||||||
switch (lhs, rhs) {
|
switch (lhs, rhs) {
|
||||||
case (.text(let lhs), .text(let rhs)):
|
case (.text(let lhs), .text(let rhs)):
|
||||||
return lhs == rhs
|
return lhs == rhs
|
||||||
|
|||||||
@@ -3,50 +3,50 @@ import XCTest
|
|||||||
|
|
||||||
final class TemplateRendererTests: XCTestCase {
|
final class TemplateRendererTests: XCTestCase {
|
||||||
func testText() throws {
|
func testText() throws {
|
||||||
let template = try HBTemplate("test text")
|
let template = try HBMustacheTemplate(string: "test text")
|
||||||
XCTAssertEqual(template.render("test"), "test text")
|
XCTAssertEqual(template.render("test"), "test text")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testStringVariable() throws {
|
func testStringVariable() throws {
|
||||||
let template = try HBTemplate("test {{.}}")
|
let template = try HBMustacheTemplate(string: "test {{.}}")
|
||||||
XCTAssertEqual(template.render("text"), "test text")
|
XCTAssertEqual(template.render("text"), "test text")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testIntegerVariable() throws {
|
func testIntegerVariable() throws {
|
||||||
let template = try HBTemplate("test {{.}}")
|
let template = try HBMustacheTemplate(string: "test {{.}}")
|
||||||
XCTAssertEqual(template.render(101), "test 101")
|
XCTAssertEqual(template.render(101), "test 101")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDictionary() throws {
|
func testDictionary() throws {
|
||||||
let template = try HBTemplate("test {{value}} {{bool}}")
|
let template = try HBMustacheTemplate(string: "test {{value}} {{bool}}")
|
||||||
XCTAssertEqual(template.render(["value": "test2", "bool": true]), "test test2 true")
|
XCTAssertEqual(template.render(["value": "test2", "bool": true]), "test test2 true")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testArraySection() throws {
|
func testArraySection() throws {
|
||||||
let template = try HBTemplate("test {{#value}}*{{.}}{{/value}}")
|
let template = try HBMustacheTemplate(string: "test {{#value}}*{{.}}{{/value}}")
|
||||||
XCTAssertEqual(template.render(["value": ["test2", "bool"]]), "test *test2*bool")
|
XCTAssertEqual(template.render(["value": ["test2", "bool"]]), "test *test2*bool")
|
||||||
XCTAssertEqual(template.render(["value": []]), "test ")
|
XCTAssertEqual(template.render(["value": []]), "test ")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testBooleanSection() throws {
|
func testBooleanSection() throws {
|
||||||
let template = try HBTemplate("test {{#.}}Yep{{/.}}")
|
let template = try HBMustacheTemplate(string: "test {{#.}}Yep{{/.}}")
|
||||||
XCTAssertEqual(template.render(true), "test Yep")
|
XCTAssertEqual(template.render(true), "test Yep")
|
||||||
XCTAssertEqual(template.render(false), "test ")
|
XCTAssertEqual(template.render(false), "test ")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testIntegerSection() throws {
|
func testIntegerSection() throws {
|
||||||
let template = try HBTemplate("test {{#.}}{{.}}{{/.}}")
|
let template = try HBMustacheTemplate(string: "test {{#.}}{{.}}{{/.}}")
|
||||||
XCTAssertEqual(template.render(23), "test 23")
|
XCTAssertEqual(template.render(23), "test 23")
|
||||||
XCTAssertEqual(template.render(0), "test ")
|
XCTAssertEqual(template.render(0), "test ")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testStringSection() throws {
|
func testStringSection() throws {
|
||||||
let template = try HBTemplate("test {{#.}}{{.}}{{/.}}")
|
let template = try HBMustacheTemplate(string: "test {{#.}}{{.}}{{/.}}")
|
||||||
XCTAssertEqual(template.render("Hello"), "test Hello")
|
XCTAssertEqual(template.render("Hello"), "test Hello")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testInvertedSection() throws {
|
func testInvertedSection() throws {
|
||||||
let template = try HBTemplate("test {{^.}}Inverted{{/.}}")
|
let template = try HBMustacheTemplate(string: "test {{^.}}Inverted{{/.}}")
|
||||||
XCTAssertEqual(template.render(true), "test ")
|
XCTAssertEqual(template.render(true), "test ")
|
||||||
XCTAssertEqual(template.render(false), "test Inverted")
|
XCTAssertEqual(template.render(false), "test Inverted")
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ final class TemplateRendererTests: XCTestCase {
|
|||||||
struct Test {
|
struct Test {
|
||||||
let string: String
|
let string: String
|
||||||
}
|
}
|
||||||
let template = try HBTemplate("test {{string}}")
|
let template = try HBMustacheTemplate(string: "test {{string}}")
|
||||||
XCTAssertEqual(template.render(Test(string: "string")), "test string")
|
XCTAssertEqual(template.render(Test(string: "string")), "test string")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ final class TemplateRendererTests: XCTestCase {
|
|||||||
struct Test {
|
struct Test {
|
||||||
let string: String?
|
let string: String?
|
||||||
}
|
}
|
||||||
let template = try HBTemplate("test {{string}}")
|
let template = try HBMustacheTemplate(string: "test {{string}}")
|
||||||
XCTAssertEqual(template.render(Test(string: "string")), "test string")
|
XCTAssertEqual(template.render(Test(string: "string")), "test string")
|
||||||
XCTAssertEqual(template.render(Test(string: nil)), "test ")
|
XCTAssertEqual(template.render(Test(string: nil)), "test ")
|
||||||
}
|
}
|
||||||
@@ -72,16 +72,16 @@ final class TemplateRendererTests: XCTestCase {
|
|||||||
struct Test {
|
struct Test {
|
||||||
let string: String?
|
let string: String?
|
||||||
}
|
}
|
||||||
let template = try HBTemplate("test {{#string}}*{{.}}{{/string}}")
|
let template = try HBMustacheTemplate(string: "test {{#string}}*{{.}}{{/string}}")
|
||||||
XCTAssertEqual(template.render(Test(string: "string")), "test *string")
|
XCTAssertEqual(template.render(Test(string: "string")), "test *string")
|
||||||
XCTAssertEqual(template.render(Test(string: nil)), "test ")
|
XCTAssertEqual(template.render(Test(string: nil)), "test ")
|
||||||
let template2 = try HBTemplate("test {{^string}}*{{/string}}")
|
let template2 = try HBMustacheTemplate(string: "test {{^string}}*{{/string}}")
|
||||||
XCTAssertEqual(template2.render(Test(string: "string")), "test ")
|
XCTAssertEqual(template2.render(Test(string: "string")), "test ")
|
||||||
XCTAssertEqual(template2.render(Test(string: nil)), "test *")
|
XCTAssertEqual(template2.render(Test(string: nil)), "test *")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDictionarySequence() throws {
|
func testDictionarySequence() throws {
|
||||||
let template = try HBTemplate("test {{#.}}{{value}}{{/.}}")
|
let template = try HBMustacheTemplate(string: "test {{#.}}{{value}}{{/.}}")
|
||||||
XCTAssert(template.render(["one": 1, "two": 2]) == "test 12" ||
|
XCTAssert(template.render(["one": 1, "two": 2]) == "test 12" ||
|
||||||
template.render(["one": 1, "two": 2]) == "test 21")
|
template.render(["one": 1, "two": 2]) == "test 21")
|
||||||
}
|
}
|
||||||
@@ -94,7 +94,69 @@ final class TemplateRendererTests: XCTestCase {
|
|||||||
let test: SubTest
|
let test: SubTest
|
||||||
}
|
}
|
||||||
|
|
||||||
let template = try HBTemplate("test {{test.string}}")
|
let template = try HBMustacheTemplate(string: "test {{test.string}}")
|
||||||
XCTAssertEqual(template.render(Test(test: .init(string: "sub"))), "test sub")
|
XCTAssertEqual(template.render(Test(test: .init(string: "sub"))), "test sub")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testMustacheManualExample1() throws {
|
||||||
|
let template = try HBMustacheTemplate(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.
|
||||||
|
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testMustacheManualExample2() throws {
|
||||||
|
let template = try HBMustacheTemplate(string: """
|
||||||
|
* {{name}}
|
||||||
|
* {{age}}
|
||||||
|
* {{company}}
|
||||||
|
* {{{company}}}
|
||||||
|
""")
|
||||||
|
let object: [String: Any] = ["name": "Chris", "company": "<b>GitHub</b>"]
|
||||||
|
XCTAssertEqual(template.render(object), """
|
||||||
|
* Chris
|
||||||
|
*
|
||||||
|
* <b>GitHub</b>
|
||||||
|
* <b>GitHub</b>
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testMustacheManualExample3() throws {
|
||||||
|
let template = try HBMustacheTemplate(string: """
|
||||||
|
Shown.
|
||||||
|
{{#person}}
|
||||||
|
Never shown!
|
||||||
|
{{/person}}
|
||||||
|
""")
|
||||||
|
let object: [String: Any] = ["person": false]
|
||||||
|
XCTAssertEqual(template.render(object), """
|
||||||
|
Shown.
|
||||||
|
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testMustacheManualExample4() throws {
|
||||||
|
let template = try HBMustacheTemplate(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>
|
||||||
|
|
||||||
|
""")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1 @@
|
|||||||
import XCTest
|
|
||||||
|
|
||||||
import hummingbird_mustacheTests
|
|
||||||
|
|
||||||
var tests = [XCTestCaseEntry]()
|
|
||||||
tests += hummingbird_mustacheTests.allTests()
|
|
||||||
XCTMain(tests)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user