Use multiline strings
multi t t
This commit is contained in:
@@ -62,11 +62,16 @@ open class SimpleErrorReporter: ErrorReporter {
|
|||||||
func describe(token: Token) -> String {
|
func describe(token: Token) -> String {
|
||||||
let templateName = token.sourceMap.filename ?? ""
|
let templateName = token.sourceMap.filename ?? ""
|
||||||
let location = token.sourceMap.location
|
let location = token.sourceMap.location
|
||||||
let highlight = "\(String(Array(repeating: " ", count: location.lineOffset)))^\(String(Array(repeating: "~", count: max(token.contents.count - 1, 0))))"
|
let highlight = """
|
||||||
|
\(String(Array(repeating: " ", count: location.lineOffset)))\
|
||||||
|
^\(String(Array(repeating: "~", count: max(token.contents.count - 1, 0))))
|
||||||
|
"""
|
||||||
|
|
||||||
return "\(templateName)\(location.lineNumber):\(location.lineOffset): error: \(templateError.reason)\n"
|
return """
|
||||||
+ "\(location.content)\n"
|
\(templateName)\(location.lineNumber):\(location.lineOffset): error: \(templateError.reason)
|
||||||
+ "\(highlight)\n"
|
\(location.content)
|
||||||
|
\(highlight)
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
var descriptions = templateError.stackTrace.reduce([]) { $0 + [describe(token: $1)] }
|
var descriptions = templateError.stackTrace.reduce([]) { $0 + [describe(token: $1)] }
|
||||||
|
|||||||
@@ -74,7 +74,9 @@ func indentFilter(value: Any?, arguments: [Any?]) throws -> Any? {
|
|||||||
var indentWidth = 4
|
var indentWidth = 4
|
||||||
if arguments.count > 0 {
|
if arguments.count > 0 {
|
||||||
guard let value = arguments[0] as? Int else {
|
guard let value = arguments[0] as? Int else {
|
||||||
throw TemplateSyntaxError("'indent' filter width argument must be an Integer (\(String(describing: arguments[0])))")
|
throw TemplateSyntaxError("""
|
||||||
|
'indent' filter width argument must be an Integer (\(String(describing: arguments[0])))
|
||||||
|
""")
|
||||||
}
|
}
|
||||||
indentWidth = value
|
indentWidth = value
|
||||||
}
|
}
|
||||||
@@ -82,7 +84,9 @@ func indentFilter(value: Any?, arguments: [Any?]) throws -> Any? {
|
|||||||
var indentationChar = " "
|
var indentationChar = " "
|
||||||
if arguments.count > 1 {
|
if arguments.count > 1 {
|
||||||
guard let value = arguments[1] as? String else {
|
guard let value = arguments[1] as? String else {
|
||||||
throw TemplateSyntaxError("'indent' filter indentation argument must be a String (\(String(describing: arguments[1]))")
|
throw TemplateSyntaxError("""
|
||||||
|
'indent' filter indentation argument must be a String (\(String(describing: arguments[1]))
|
||||||
|
""")
|
||||||
}
|
}
|
||||||
indentationChar = value
|
indentationChar = value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,11 @@ class IncludeNode : NodeType {
|
|||||||
let bits = token.components()
|
let bits = token.components()
|
||||||
|
|
||||||
guard bits.count == 2 || bits.count == 3 else {
|
guard bits.count == 2 || bits.count == 3 else {
|
||||||
throw TemplateSyntaxError("'include' tag requires one argument, the template file to be included. A second optional argument can be used to specify the context that will be passed to the included file")
|
throw TemplateSyntaxError("""
|
||||||
|
'include' tag requires one argument, the template file to be included. \
|
||||||
|
A second optional argument can be used to specify the context that will \
|
||||||
|
be passed to the included file
|
||||||
|
""")
|
||||||
}
|
}
|
||||||
|
|
||||||
return IncludeNode(templateName: Variable(bits[1]), includeContext: bits.count == 3 ? bits[2] : nil, token: token)
|
return IncludeNode(templateName: Variable(bits[1]), includeContext: bits.count == 3 ? bits[2] : nil, token: token)
|
||||||
|
|||||||
@@ -98,7 +98,10 @@ public class TokenParser {
|
|||||||
if suggestedFilters.isEmpty {
|
if suggestedFilters.isEmpty {
|
||||||
throw TemplateSyntaxError("Unknown filter '\(name)'.")
|
throw TemplateSyntaxError("Unknown filter '\(name)'.")
|
||||||
} else {
|
} else {
|
||||||
throw TemplateSyntaxError("Unknown filter '\(name)'. Found similar filters: \(suggestedFilters.map({ "'\($0)'" }).joined(separator: ", ")).")
|
throw TemplateSyntaxError("""
|
||||||
|
Unknown filter '\(name)'. \
|
||||||
|
Found similar filters: \(suggestedFilters.map({ "'\($0)'" }).joined(separator: ", ")).
|
||||||
|
""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -218,11 +218,15 @@ func testEnvironment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$0.it("reports syntax error in included template") {
|
$0.it("reports syntax error in included template") {
|
||||||
template = Template(templateString: "{% include \"invalid-include.html\" %}", environment: environment)
|
template = Template(templateString: """
|
||||||
|
{% include "invalid-include.html" %}
|
||||||
|
""", environment: environment)
|
||||||
includedTemplate = try environment.loadTemplate(name: "invalid-include.html")
|
includedTemplate = try environment.loadTemplate(name: "invalid-include.html")
|
||||||
|
|
||||||
try expectError(reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.",
|
try expectError(reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.",
|
||||||
token: "include \"invalid-include.html\"",
|
token: """
|
||||||
|
include "invalid-include.html"
|
||||||
|
""",
|
||||||
includedToken: "target|unknown")
|
includedToken: "target|unknown")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +237,9 @@ func testEnvironment() {
|
|||||||
})
|
})
|
||||||
environment.extensions += [filterExtension]
|
environment.extensions += [filterExtension]
|
||||||
|
|
||||||
template = Template(templateString: "{% include \"invalid-include.html\" %}", environment: environment)
|
template = Template(templateString: """
|
||||||
|
{% include "invalid-include.html" %}
|
||||||
|
""", environment: environment)
|
||||||
includedTemplate = try environment.loadTemplate(name: "invalid-include.html")
|
includedTemplate = try environment.loadTemplate(name: "invalid-include.html")
|
||||||
|
|
||||||
try expectError(reason: "filter error",
|
try expectError(reason: "filter error",
|
||||||
@@ -293,8 +299,10 @@ func testEnvironment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$0.it("reports syntax error in child template") {
|
$0.it("reports syntax error in child template") {
|
||||||
childTemplate = Template(templateString: "{% extends \"base.html\" %}\n" +
|
childTemplate = Template(templateString: """
|
||||||
"{% block body %}Child {{ target|unknown }}{% endblock %}", environment: environment, name: nil)
|
{% extends "base.html" %}
|
||||||
|
{% block body %}Child {{ target|unknown }}{% endblock %}
|
||||||
|
""", environment: environment, name: nil)
|
||||||
|
|
||||||
try expectError(reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.",
|
try expectError(reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.",
|
||||||
childToken: "target|unknown",
|
childToken: "target|unknown",
|
||||||
@@ -308,8 +316,10 @@ func testEnvironment() {
|
|||||||
})
|
})
|
||||||
environment.extensions += [filterExtension]
|
environment.extensions += [filterExtension]
|
||||||
|
|
||||||
childTemplate = Template(templateString: "{% extends \"base.html\" %}\n" +
|
childTemplate = Template(templateString: """
|
||||||
"{% block body %}Child {{ target|unknown }}{% endblock %}", environment: environment, name: nil)
|
{% extends "base.html" %}
|
||||||
|
{% block body %}Child {{ target|unknown }}{% endblock %}
|
||||||
|
""", environment: environment, name: nil)
|
||||||
|
|
||||||
try expectError(reason: "filter error",
|
try expectError(reason: "filter error",
|
||||||
childToken: "target|unknown",
|
childToken: "target|unknown",
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ func testFilter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$0.it("allows you to register a custom filter which accepts single argument") {
|
$0.it("allows you to register a custom filter which accepts single argument") {
|
||||||
let template = Template(templateString: "{{ name|repeat:'value1, \"value2\"' }}")
|
let template = Template(templateString: """
|
||||||
|
{{ name|repeat:'value1, "value2"' }}
|
||||||
|
""")
|
||||||
|
|
||||||
let repeatExtension = Extension()
|
let repeatExtension = Extension()
|
||||||
repeatExtension.registerFilter("repeat") { value, arguments in
|
repeatExtension.registerFilter("repeat") { value, arguments in
|
||||||
@@ -35,11 +37,15 @@ func testFilter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let result = try template.render(Context(dictionary: context, environment: Environment(extensions: [repeatExtension])))
|
let result = try template.render(Context(dictionary: context, environment: Environment(extensions: [repeatExtension])))
|
||||||
try expect(result) == "Kyle Kyle with args value1, \"value2\""
|
try expect(result) == """
|
||||||
|
Kyle Kyle with args value1, "value2"
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.it("allows you to register a custom filter which accepts several arguments") {
|
$0.it("allows you to register a custom filter which accepts several arguments") {
|
||||||
let template = Template(templateString: "{{ name|repeat:'value\"1\"',\"value'2'\",'(key, value)' }}")
|
let template = Template(templateString: """
|
||||||
|
{{ name|repeat:'value"1"',"value'2'",'(key, value)' }}
|
||||||
|
""")
|
||||||
|
|
||||||
let repeatExtension = Extension()
|
let repeatExtension = Extension()
|
||||||
repeatExtension.registerFilter("repeat") { value, arguments in
|
repeatExtension.registerFilter("repeat") { value, arguments in
|
||||||
@@ -51,7 +57,9 @@ func testFilter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let result = try template.render(Context(dictionary: context, environment: Environment(extensions: [repeatExtension])))
|
let result = try template.render(Context(dictionary: context, environment: Environment(extensions: [repeatExtension])))
|
||||||
try expect(result) == "Kyle Kyle with args 0: value\"1\", 1: value'2', 2: (key, value)"
|
try expect(result) == """
|
||||||
|
Kyle Kyle with args 0: value"1", 1: value'2', 2: (key, value)
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.it("allows you to register a custom which throws") {
|
$0.it("allows you to register a custom which throws") {
|
||||||
@@ -78,7 +86,9 @@ func testFilter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$0.it("allows whitespace in expression") {
|
$0.it("allows whitespace in expression") {
|
||||||
let template = Template(templateString: "{{ value | join : \", \" }}")
|
let template = Template(templateString: """
|
||||||
|
{{ value | join : ", " }}
|
||||||
|
""")
|
||||||
let result = try template.render(Context(dictionary: ["value": ["One", "Two"]]))
|
let result = try template.render(Context(dictionary: ["value": ["One", "Two"]]))
|
||||||
try expect(result) == "One, Two"
|
try expect(result) == "One, Two"
|
||||||
}
|
}
|
||||||
@@ -114,25 +124,33 @@ func testFilter() {
|
|||||||
$0.it("transforms a string to be capitalized") {
|
$0.it("transforms a string to be capitalized") {
|
||||||
let template = Template(templateString: "{{ names|capitalize }}")
|
let template = Template(templateString: "{{ names|capitalize }}")
|
||||||
let result = try template.render(Context(dictionary: ["names": ["kyle", "kyle"]]))
|
let result = try template.render(Context(dictionary: ["names": ["kyle", "kyle"]]))
|
||||||
try expect(result) == "[\"Kyle\", \"Kyle\"]"
|
try expect(result) == """
|
||||||
|
["Kyle", "Kyle"]
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.it("transforms a string to be uppercase") {
|
$0.it("transforms a string to be uppercase") {
|
||||||
let template = Template(templateString: "{{ names|uppercase }}")
|
let template = Template(templateString: "{{ names|uppercase }}")
|
||||||
let result = try template.render(Context(dictionary: ["names": ["kyle", "kyle"]]))
|
let result = try template.render(Context(dictionary: ["names": ["kyle", "kyle"]]))
|
||||||
try expect(result) == "[\"KYLE\", \"KYLE\"]"
|
try expect(result) == """
|
||||||
|
["KYLE", "KYLE"]
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.it("transforms a string to be lowercase") {
|
$0.it("transforms a string to be lowercase") {
|
||||||
let template = Template(templateString: "{{ names|lowercase }}")
|
let template = Template(templateString: "{{ names|lowercase }}")
|
||||||
let result = try template.render(Context(dictionary: ["names": ["Kyle", "Kyle"]]))
|
let result = try template.render(Context(dictionary: ["names": ["Kyle", "Kyle"]]))
|
||||||
try expect(result) == "[\"kyle\", \"kyle\"]"
|
try expect(result) == """
|
||||||
|
["kyle", "kyle"]
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("default filter") {
|
describe("default filter") {
|
||||||
let template = Template(templateString: "Hello {{ name|default:\"World\" }}")
|
let template = Template(templateString: """
|
||||||
|
Hello {{ name|default:"World" }}
|
||||||
|
""")
|
||||||
|
|
||||||
$0.it("shows the variable value") {
|
$0.it("shows the variable value") {
|
||||||
let result = try template.render(Context(dictionary: ["name": "Kyle"]))
|
let result = try template.render(Context(dictionary: ["name": "Kyle"]))
|
||||||
@@ -145,7 +163,9 @@ func testFilter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$0.it("supports multiple defaults") {
|
$0.it("supports multiple defaults") {
|
||||||
let template = Template(templateString: "Hello {{ name|default:a,b,c,\"World\" }}")
|
let template = Template(templateString: """
|
||||||
|
Hello {{ name|default:a,b,c,"World" }}
|
||||||
|
""")
|
||||||
let result = try template.render(Context(dictionary: [:]))
|
let result = try template.render(Context(dictionary: [:]))
|
||||||
try expect(result) == "Hello World"
|
try expect(result) == "Hello World"
|
||||||
}
|
}
|
||||||
@@ -163,7 +183,9 @@ func testFilter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$0.it("checks for underlying nil value correctly") {
|
$0.it("checks for underlying nil value correctly") {
|
||||||
let template = Template(templateString: "Hello {{ user.name|default:\"anonymous\" }}")
|
let template = Template(templateString: """
|
||||||
|
Hello {{ user.name|default:"anonymous" }}
|
||||||
|
""")
|
||||||
let nilName: String? = nil
|
let nilName: String? = nil
|
||||||
let user: [String: Any?] = ["name": nilName]
|
let user: [String: Any?] = ["name": nilName]
|
||||||
let result = try template.render(Context(dictionary: ["user": user]))
|
let result = try template.render(Context(dictionary: ["user": user]))
|
||||||
@@ -172,7 +194,9 @@ func testFilter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe("join filter") {
|
describe("join filter") {
|
||||||
let template = Template(templateString: "{{ value|join:\", \" }}")
|
let template = Template(templateString: """
|
||||||
|
{{ value|join:", " }}
|
||||||
|
""")
|
||||||
|
|
||||||
$0.it("joins a collection of strings") {
|
$0.it("joins a collection of strings") {
|
||||||
let result = try template.render(Context(dictionary: ["value": ["One", "Two"]]))
|
let result = try template.render(Context(dictionary: ["value": ["One", "Two"]]))
|
||||||
@@ -185,30 +209,42 @@ func testFilter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$0.it("can join by non string") {
|
$0.it("can join by non string") {
|
||||||
let template = Template(templateString: "{{ value|join:separator }}")
|
let template = Template(templateString: """
|
||||||
|
{{ value|join:separator }}
|
||||||
|
""")
|
||||||
let result = try template.render(Context(dictionary: ["value": ["One", "Two"], "separator": true]))
|
let result = try template.render(Context(dictionary: ["value": ["One", "Two"], "separator": true]))
|
||||||
try expect(result) == "OnetrueTwo"
|
try expect(result) == "OnetrueTwo"
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.it("can join without arguments") {
|
$0.it("can join without arguments") {
|
||||||
let template = Template(templateString: "{{ value|join }}")
|
let template = Template(templateString: """
|
||||||
|
{{ value|join }}
|
||||||
|
""")
|
||||||
let result = try template.render(Context(dictionary: ["value": ["One", "Two"]]))
|
let result = try template.render(Context(dictionary: ["value": ["One", "Two"]]))
|
||||||
try expect(result) == "OneTwo"
|
try expect(result) == "OneTwo"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("split filter") {
|
describe("split filter") {
|
||||||
let template = Template(templateString: "{{ value|split:\", \" }}")
|
let template = Template(templateString: """
|
||||||
|
{{ value|split:", " }}
|
||||||
|
""")
|
||||||
|
|
||||||
$0.it("split a string into array") {
|
$0.it("split a string into array") {
|
||||||
let result = try template.render(Context(dictionary: ["value": "One, Two"]))
|
let result = try template.render(Context(dictionary: ["value": "One, Two"]))
|
||||||
try expect(result) == "[\"One\", \"Two\"]"
|
try expect(result) == """
|
||||||
|
["One", "Two"]
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.it("can split without arguments") {
|
$0.it("can split without arguments") {
|
||||||
let template = Template(templateString: "{{ value|split }}")
|
let template = Template(templateString: """
|
||||||
|
{{ value|split }}
|
||||||
|
""")
|
||||||
let result = try template.render(Context(dictionary: ["value": "One, Two"]))
|
let result = try template.render(Context(dictionary: ["value": "One, Two"]))
|
||||||
try expect(result) == "[\"One,\", \"Two\"]"
|
try expect(result) == """
|
||||||
|
["One,", "Two"]
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,27 +304,67 @@ func testFilter() {
|
|||||||
|
|
||||||
describe("indent filter") {
|
describe("indent filter") {
|
||||||
$0.it("indents content") {
|
$0.it("indents content") {
|
||||||
let template = Template(templateString: "{{ value|indent:2 }}")
|
let template = Template(templateString: """
|
||||||
let result = try template.render(Context(dictionary: ["value": "One\nTwo"]))
|
{{ value|indent:2 }}
|
||||||
try expect(result) == "One\n Two"
|
""")
|
||||||
|
let result = try template.render(Context(dictionary: ["value": """
|
||||||
|
One
|
||||||
|
Two
|
||||||
|
"""]))
|
||||||
|
try expect(result) == """
|
||||||
|
One
|
||||||
|
Two
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.it("can indent with arbitrary character") {
|
$0.it("can indent with arbitrary character") {
|
||||||
let template = Template(templateString: "{{ value|indent:2,\"\t\" }}")
|
let template = Template(templateString: """
|
||||||
let result = try template.render(Context(dictionary: ["value": "One\nTwo"]))
|
{{ value|indent:2,"\t" }}
|
||||||
try expect(result) == "One\n\t\tTwo"
|
""")
|
||||||
|
let result = try template.render(Context(dictionary: ["value": """
|
||||||
|
One
|
||||||
|
Two
|
||||||
|
"""]))
|
||||||
|
try expect(result) == """
|
||||||
|
One
|
||||||
|
\t\tTwo
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.it("can indent first line") {
|
$0.it("can indent first line") {
|
||||||
let template = Template(templateString: "{{ value|indent:2,\" \",true }}")
|
let template = Template(templateString: """
|
||||||
let result = try template.render(Context(dictionary: ["value": "One\nTwo"]))
|
{{ value|indent:2," ",true }}
|
||||||
try expect(result) == " One\n Two"
|
""")
|
||||||
|
let result = try template.render(Context(dictionary: ["value": """
|
||||||
|
One
|
||||||
|
Two
|
||||||
|
"""]))
|
||||||
|
try expect(result) == """
|
||||||
|
One
|
||||||
|
Two
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.it("does not indent empty lines") {
|
$0.it("does not indent empty lines") {
|
||||||
let template = Template(templateString: "{{ value|indent }}")
|
let template = Template(templateString: """
|
||||||
let result = try template.render(Context(dictionary: ["value": "One\n\n\nTwo\n\n"]))
|
{{ value|indent }}
|
||||||
try expect(result) == "One\n\n\n Two\n\n"
|
""")
|
||||||
|
let result = try template.render(Context(dictionary: ["value": """
|
||||||
|
One
|
||||||
|
|
||||||
|
|
||||||
|
Two
|
||||||
|
|
||||||
|
|
||||||
|
"""]))
|
||||||
|
try expect(result) == """
|
||||||
|
One
|
||||||
|
|
||||||
|
|
||||||
|
Two
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ func testFilterTag() {
|
|||||||
return ($0 as! String).components(separatedBy: $1[0] as! String)
|
return ($0 as! String).components(separatedBy: $1[0] as! String)
|
||||||
})
|
})
|
||||||
let env = Environment(extensions: [ext])
|
let env = Environment(extensions: [ext])
|
||||||
let result = try env.renderTemplate(string: "{% filter split:\",\"|join:\";\" %}{{ items|join:\",\" }}{% endfilter %}", context: ["items": [1, 2]])
|
let result = try env.renderTemplate(string: """
|
||||||
|
{% filter split:","|join:";" %}{{ items|join:"," }}{% endfilter %}
|
||||||
|
""", context: ["items": [1, 2]])
|
||||||
try expect(result) == "1;2"
|
try expect(result) == "1;2"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +40,9 @@ func testFilterTag() {
|
|||||||
return ($0 as! String).replacingOccurrences(of: $1[0] as! String, with: $1[1] as! String)
|
return ($0 as! String).replacingOccurrences(of: $1[0] as! String, with: $1[1] as! String)
|
||||||
})
|
})
|
||||||
let env = Environment(extensions: [ext])
|
let env = Environment(extensions: [ext])
|
||||||
let result = try env.renderTemplate(string: "{% filter replace:'\"',\"\" %}{{ items|join:\",\" }}{% endfilter %}", context: ["items": ["\"1\"", "\"2\""]])
|
let result = try env.renderTemplate(string: """
|
||||||
|
{% filter replace:'"',"" %}{{ items|join:"," }}{% endfilter %}
|
||||||
|
""", context: ["items": ["\"1\"", "\"2\""]])
|
||||||
try expect(result) == "1,2"
|
try expect(result) == "1,2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,9 +112,11 @@ func testForNode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$0.it("can render a filter with spaces") {
|
$0.it("can render a filter with spaces") {
|
||||||
let templateString = "{% for article in ars | default: a, b , articles %}" +
|
let templateString = """
|
||||||
"- {{ article.title }} by {{ article.author }}.\n" +
|
{% for article in ars | default: a, b , articles %}\
|
||||||
"{% endfor %}\n"
|
- {{ article.title }} by {{ article.author }}.
|
||||||
|
{% endfor %}
|
||||||
|
"""
|
||||||
|
|
||||||
let context = Context(dictionary: [
|
let context = Context(dictionary: [
|
||||||
"articles": [
|
"articles": [
|
||||||
@@ -126,54 +128,70 @@ func testForNode() {
|
|||||||
let template = Template(templateString: templateString)
|
let template = Template(templateString: templateString)
|
||||||
let result = try template.render(context)
|
let result = try template.render(context)
|
||||||
|
|
||||||
let fixture = "" +
|
try expect(result) == """
|
||||||
"- Migrating from OCUnit to XCTest by Kyle Fuller.\n" +
|
- Migrating from OCUnit to XCTest by Kyle Fuller.
|
||||||
"- Memory Management with ARC by Kyle Fuller.\n" +
|
- Memory Management with ARC by Kyle Fuller.
|
||||||
"\n"
|
|
||||||
|
|
||||||
try expect(result) == fixture
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.context("given array of tuples") {
|
$0.context("given array of tuples") {
|
||||||
$0.it("can iterate over all tuple values") {
|
$0.it("can iterate over all tuple values") {
|
||||||
let templateString = "{% for first,second,third in tuples %}" +
|
let templateString = """
|
||||||
"{{ first }}, {{ second }}, {{ third }}\n" +
|
{% for first,second,third in tuples %}\
|
||||||
"{% endfor %}\n"
|
{{ first }}, {{ second }}, {{ third }}
|
||||||
|
{% endfor %}
|
||||||
|
"""
|
||||||
|
|
||||||
let template = Template(templateString: templateString)
|
let template = Template(templateString: templateString)
|
||||||
let result = try template.render(context)
|
let result = try template.render(context)
|
||||||
|
|
||||||
let fixture = "1, 2, 3\n4, 5, 6\n\n"
|
try expect(result) == """
|
||||||
try expect(result) == fixture
|
1, 2, 3
|
||||||
|
4, 5, 6
|
||||||
|
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.it("can iterate with less number of variables") {
|
$0.it("can iterate with less number of variables") {
|
||||||
let templateString = "{% for first,second in tuples %}" +
|
let templateString = """
|
||||||
"{{ first }}, {{ second }}\n" +
|
{% for first,second in tuples %}\
|
||||||
"{% endfor %}\n"
|
{{ first }}, {{ second }}
|
||||||
|
{% endfor %}
|
||||||
|
"""
|
||||||
|
|
||||||
let template = Template(templateString: templateString)
|
let template = Template(templateString: templateString)
|
||||||
let result = try template.render(context)
|
let result = try template.render(context)
|
||||||
|
|
||||||
let fixture = "1, 2\n4, 5\n\n"
|
try expect(result) == """
|
||||||
try expect(result) == fixture
|
1, 2
|
||||||
|
4, 5
|
||||||
|
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.it("can use _ to skip variables") {
|
$0.it("can use _ to skip variables") {
|
||||||
let templateString = "{% for first,_,third in tuples %}" +
|
let templateString = """
|
||||||
"{{ first }}, {{ third }}\n" +
|
{% for first,_,third in tuples %}\
|
||||||
"{% endfor %}\n"
|
{{ first }}, {{ third }}
|
||||||
|
{% endfor %}
|
||||||
|
"""
|
||||||
|
|
||||||
let template = Template(templateString: templateString)
|
let template = Template(templateString: templateString)
|
||||||
let result = try template.render(context)
|
let result = try template.render(context)
|
||||||
|
|
||||||
let fixture = "1, 3\n4, 6\n\n"
|
try expect(result) == """
|
||||||
try expect(result) == fixture
|
1, 3
|
||||||
|
4, 6
|
||||||
|
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.it("throws when number of variables is more than number of tuple values") {
|
$0.it("throws when number of variables is more than number of tuple values") {
|
||||||
let templateString = "{% for key,value,smth in dict %}" +
|
let templateString = """
|
||||||
"{% endfor %}\n"
|
{% for key,value,smth in dict %}
|
||||||
|
{% endfor %}
|
||||||
|
"""
|
||||||
|
|
||||||
let template = Template(templateString: templateString)
|
let template = Template(templateString: templateString)
|
||||||
try expect(template.render(context)).toThrow()
|
try expect(template.render(context)).toThrow()
|
||||||
@@ -182,9 +200,11 @@ func testForNode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$0.it("can iterate over dictionary") {
|
$0.it("can iterate over dictionary") {
|
||||||
let templateString = "{% for key, value in dict %}" +
|
let templateString = """
|
||||||
"{{ key }}: {{ value }}," +
|
{% for key, value in dict %}\
|
||||||
"{% endfor %}"
|
{{ key }}: {{ value }},\
|
||||||
|
{% endfor %}
|
||||||
|
"""
|
||||||
|
|
||||||
let template = Template(templateString: templateString)
|
let template = Template(templateString: templateString)
|
||||||
let result = try template.render(context)
|
let result = try template.render(context)
|
||||||
@@ -248,7 +268,11 @@ func testForNode() {
|
|||||||
let node = ForNode(resolvable: Variable("struct"), loopVariables: ["property", "value"], nodes: nodes, emptyNodes: [])
|
let node = ForNode(resolvable: Variable("struct"), loopVariables: ["property", "value"], nodes: nodes, emptyNodes: [])
|
||||||
let result = try node.render(context)
|
let result = try node.render(context)
|
||||||
|
|
||||||
try expect(result) == "string=abc\nnumber=123\n"
|
try expect(result) == """
|
||||||
|
string=abc
|
||||||
|
number=123
|
||||||
|
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.it("can iterate tuple items") {
|
$0.it("can iterate tuple items") {
|
||||||
@@ -266,7 +290,11 @@ func testForNode() {
|
|||||||
let node = ForNode(resolvable: Variable("tuple"), loopVariables: ["label", "value"], nodes: nodes, emptyNodes: [])
|
let node = ForNode(resolvable: Variable("tuple"), loopVariables: ["label", "value"], nodes: nodes, emptyNodes: [])
|
||||||
let result = try node.render(context)
|
let result = try node.render(context)
|
||||||
|
|
||||||
try expect(result) == "one=1\ntwo=dva\n"
|
try expect(result) == """
|
||||||
|
one=1
|
||||||
|
two=dva
|
||||||
|
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.it("can iterate over class properties") {
|
$0.it("can iterate over class properties") {
|
||||||
@@ -301,7 +329,12 @@ func testForNode() {
|
|||||||
let node = ForNode(resolvable: Variable("class"), loopVariables: ["label", "value"], nodes: nodes, emptyNodes: [])
|
let node = ForNode(resolvable: Variable("class"), loopVariables: ["label", "value"], nodes: nodes, emptyNodes: [])
|
||||||
let result = try node.render(context)
|
let result = try node.render(context)
|
||||||
|
|
||||||
try expect(result) == "childString=child\nbaseString=base\nbaseInt=1\n"
|
try expect(result) == """
|
||||||
|
childString=child
|
||||||
|
baseString=base
|
||||||
|
baseInt=1
|
||||||
|
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.it("can iterate in range of variables") {
|
$0.it("can iterate in range of variables") {
|
||||||
@@ -313,7 +346,6 @@ func testForNode() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fileprivate struct Article {
|
fileprivate struct Article {
|
||||||
let title: String
|
let title: String
|
||||||
let author: String
|
let author: String
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ func testInclude() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$0.it("successfully passes context") {
|
$0.it("successfully passes context") {
|
||||||
let template = Template(templateString: "{% include \"test.html\" child %}")
|
let template = Template(templateString: """
|
||||||
|
{% include "test.html" child %}
|
||||||
|
""")
|
||||||
let context = Context(dictionary: ["child": ["target": "World"]], environment: environment)
|
let context = Context(dictionary: ["child": ["target": "World"]], environment: environment)
|
||||||
let value = try template.render(context)
|
let value = try template.render(context)
|
||||||
try expect(value) == "Hello World!"
|
try expect(value) == "Hello World!"
|
||||||
|
|||||||
@@ -11,17 +11,26 @@ func testInheritence() {
|
|||||||
|
|
||||||
$0.it("can inherit from another template") {
|
$0.it("can inherit from another template") {
|
||||||
let template = try environment.loadTemplate(name: "child.html")
|
let template = try environment.loadTemplate(name: "child.html")
|
||||||
try expect(try template.render()) == "Super_Header Child_Header\nChild_Body"
|
try expect(try template.render()) == """
|
||||||
|
Super_Header Child_Header
|
||||||
|
Child_Body
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.it("can inherit from another template inheriting from another template") {
|
$0.it("can inherit from another template inheriting from another template") {
|
||||||
let template = try environment.loadTemplate(name: "child-child.html")
|
let template = try environment.loadTemplate(name: "child-child.html")
|
||||||
try expect(try template.render()) == "Super_Header Child_Header Child_Child_Header\nChild_Body"
|
try expect(try template.render()) == """
|
||||||
|
Super_Header Child_Header Child_Child_Header
|
||||||
|
Child_Body
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.it("can inherit from a template that calls a super block") {
|
$0.it("can inherit from a template that calls a super block") {
|
||||||
let template = try environment.loadTemplate(name: "child-super.html")
|
let template = try environment.loadTemplate(name: "child-super.html")
|
||||||
try expect(try template.render()) == "Header\nChild_Body"
|
try expect(try template.render()) == """
|
||||||
|
Header
|
||||||
|
Child_Body
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,15 +69,16 @@ func testLexer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$0.it("can tokenize with new lines") {
|
$0.it("can tokenize with new lines") {
|
||||||
let templateString =
|
let templateString = """
|
||||||
"My name is {%\n" +
|
My name is {%
|
||||||
" if name\n" +
|
if name
|
||||||
" and\n" +
|
and
|
||||||
" name\n" +
|
name
|
||||||
"%}{{\n" +
|
%}{{
|
||||||
"name\n" +
|
name
|
||||||
"}}{%\n" +
|
}}{%
|
||||||
"endif %}."
|
endif %}.
|
||||||
|
"""
|
||||||
|
|
||||||
let lexer = Lexer(templateString: templateString)
|
let lexer = Lexer(templateString: templateString)
|
||||||
|
|
||||||
|
|||||||
@@ -32,11 +32,13 @@ func testStencil() {
|
|||||||
|
|
||||||
$0.it("can render the README example") {
|
$0.it("can render the README example") {
|
||||||
|
|
||||||
let templateString = "There are {{ articles.count }} articles.\n" +
|
let templateString = """
|
||||||
"\n" +
|
There are {{ articles.count }} articles.
|
||||||
"{% for article in articles %}" +
|
|
||||||
" - {{ article.title }} by {{ article.author }}.\n" +
|
{% for article in articles %}\
|
||||||
"{% endfor %}\n"
|
- {{ article.title }} by {{ article.author }}.
|
||||||
|
{% endfor %}
|
||||||
|
"""
|
||||||
|
|
||||||
let context = [
|
let context = [
|
||||||
"articles": [
|
"articles": [
|
||||||
@@ -48,13 +50,13 @@ func testStencil() {
|
|||||||
let template = Template(templateString: templateString)
|
let template = Template(templateString: templateString)
|
||||||
let result = try template.render(context)
|
let result = try template.render(context)
|
||||||
|
|
||||||
let fixture = "There are 2 articles.\n" +
|
try expect(result) == """
|
||||||
"\n" +
|
There are 2 articles.
|
||||||
" - Migrating from OCUnit to XCTest by Kyle Fuller.\n" +
|
|
||||||
" - Memory Management with ARC by Kyle Fuller.\n" +
|
|
||||||
"\n"
|
|
||||||
|
|
||||||
try expect(result) == fixture
|
- Migrating from OCUnit to XCTest by Kyle Fuller.
|
||||||
|
- Memory Management with ARC by Kyle Fuller.
|
||||||
|
|
||||||
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
$0.it("can render a custom template tag") {
|
$0.it("can render a custom template tag") {
|
||||||
|
|||||||
Reference in New Issue
Block a user