diff --git a/Sources/Errors.swift b/Sources/Errors.swift index 787688a..a6191f9 100644 --- a/Sources/Errors.swift +++ b/Sources/Errors.swift @@ -62,11 +62,16 @@ open class SimpleErrorReporter: ErrorReporter { func describe(token: Token) -> String { let templateName = token.sourceMap.filename ?? "" 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" - + "\(location.content)\n" - + "\(highlight)\n" + return """ + \(templateName)\(location.lineNumber):\(location.lineOffset): error: \(templateError.reason) + \(location.content) + \(highlight) + """ } var descriptions = templateError.stackTrace.reduce([]) { $0 + [describe(token: $1)] } diff --git a/Sources/Filters.swift b/Sources/Filters.swift index fece6eb..9832123 100644 --- a/Sources/Filters.swift +++ b/Sources/Filters.swift @@ -74,7 +74,9 @@ func indentFilter(value: Any?, arguments: [Any?]) throws -> Any? { var indentWidth = 4 if arguments.count > 0 { 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 } @@ -82,7 +84,9 @@ func indentFilter(value: Any?, arguments: [Any?]) throws -> Any? { var indentationChar = " " if arguments.count > 1 { 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 } diff --git a/Sources/Include.swift b/Sources/Include.swift index 6dd331c..d6287cc 100644 --- a/Sources/Include.swift +++ b/Sources/Include.swift @@ -10,7 +10,11 @@ class IncludeNode : NodeType { let bits = token.components() 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) diff --git a/Sources/Parser.swift b/Sources/Parser.swift index 817b5fd..5de93e8 100644 --- a/Sources/Parser.swift +++ b/Sources/Parser.swift @@ -98,7 +98,10 @@ public class TokenParser { if suggestedFilters.isEmpty { throw TemplateSyntaxError("Unknown filter '\(name)'.") } 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: ", ")). + """) } } diff --git a/Tests/StencilTests/EnvironmentSpec.swift b/Tests/StencilTests/EnvironmentSpec.swift index 4c8abed..04ce6c1 100644 --- a/Tests/StencilTests/EnvironmentSpec.swift +++ b/Tests/StencilTests/EnvironmentSpec.swift @@ -7,7 +7,7 @@ func testEnvironment() { describe("Environment") { var environment: Environment! var template: Template! - + $0.before { environment = Environment(loader: ExampleLoader()) template = nil @@ -54,7 +54,7 @@ func testEnvironment() { func expectError(reason: String, token: String, file: String = #file, line: Int = #line, function: String = #function) throws { let expectedError = expectedSyntaxError(token: token, template: template, description: reason) - + let error = try expect(environment.render(template: template, context: ["names": ["Bob", "Alice"], "name": "Bob"]), file: file, line: line, function: function).toThrow() as TemplateSyntaxError let reporter = SimpleErrorReporter() @@ -67,58 +67,58 @@ func testEnvironment() { template = "Hello {% for name in %}{{ name }}, {% endfor %}!" try expectError(reason: "'for' statements should use the syntax: `for in [where ]`.", token: "for name in") } - + $0.it("reports syntax error on missing endfor") { template = "{% for name in names %}{{ name }}" try expectError(reason: "`endfor` was not found.", token: "for name in names") } - + $0.it("reports syntax error on unknown tag") { template = "{% for name in names %}{{ name }}{% end %}" try expectError(reason: "Unknown template tag 'end'", token: "end") } } - + $0.context("given unknown filter") { $0.it("reports syntax error in for tag") { template = "{% for name in names|unknown %}{{ name }}{% endfor %}" try expectError(reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.", token: "names|unknown") } - + $0.it("reports syntax error in for-where tag") { template = "{% for name in names where name|unknown %}{{ name }}{% endfor %}" try expectError(reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.", token: "name|unknown") } - + $0.it("reports syntax error in if tag") { template = "{% if name|unknown %}{{ name }}{% endif %}" try expectError(reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.", token: "name|unknown") } - + $0.it("reports syntax error in elif tag") { template = "{% if name %}{{ name }}{% elif name|unknown %}{% endif %}" try expectError(reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.", token: "name|unknown") } - + $0.it("reports syntax error in ifnot tag") { template = "{% ifnot name|unknown %}{{ name }}{% endif %}" try expectError(reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.", token: "name|unknown") } - + $0.it("reports syntax error in filter tag") { template = "{% filter unknown %}Text{% endfilter %}" try expectError(reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.", token: "filter unknown") } - + $0.it("reports syntax error in variable tag") { template = "{{ name|unknown }}" try expectError(reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.", token: "name|unknown") } } - + $0.context("given rendering error") { $0.it("reports rendering error in variable filter") { @@ -131,7 +131,7 @@ func testEnvironment() { template = Template(templateString: "{{ name|throw }}", environment: environment) try expectError(reason: "filter error", token: "name|throw") } - + $0.it("reports rendering error in filter tag") { let filterExtension = Extension() filterExtension.registerFilter("throw") { (value: Any?) in @@ -142,7 +142,7 @@ func testEnvironment() { template = Template(templateString: "{% filter throw %}Test{% endfilter %}", environment: environment) try expectError(reason: "filter error", token: "filter throw") } - + $0.it("reports rendering error in simple tag") { let tagExtension = Extension() tagExtension.registerSimpleTag("simpletag") { context in @@ -153,23 +153,23 @@ func testEnvironment() { template = Template(templateString: "{% simpletag %}", environment: environment) try expectError(reason: "simpletag error", token: "simpletag") } - + $0.it("reporsts passing argument to simple filter") { template = "{{ name|uppercase:5 }}" try expectError(reason: "cannot invoke filter with an argument", token: "name|uppercase:5") } - + $0.it("reports rendering error in custom tag") { let tagExtension = Extension() tagExtension.registerTag("customtag") { parser, token in return ErrorNode(token: token) } environment.extensions += [tagExtension] - + template = Template(templateString: "{% customtag %}", environment: environment) try expectError(reason: "Custom Error", token: "customtag") } - + $0.it("reports rendering error in for body") { let tagExtension = Extension() tagExtension.registerTag("customtag") { parser, token in @@ -180,7 +180,7 @@ func testEnvironment() { template = Template(templateString: "{% for name in names %}{% customtag %}{% endfor %}", environment: environment) try expectError(reason: "Custom Error", token: "customtag") } - + $0.it("reports rendering error in block") { let tagExtension = Extension() tagExtension.registerTag("customtag") { parser, token in @@ -192,48 +192,54 @@ func testEnvironment() { try expectError(reason: "Custom Error", token: "customtag") } } - + $0.context("given included template") { let path = Path(#file) + ".." + "fixtures" let loader = FileSystemLoader(paths: [path]) var environment = Environment(loader: loader) var template: Template! var includedTemplate: Template! - + $0.before { environment = Environment(loader: loader) template = nil includedTemplate = nil } - + func expectError(reason: String, token: String, includedToken: String, file: String = #file, line: Int = #line, function: String = #function) throws { var expectedError = expectedSyntaxError(token: token, template: template, description: reason) expectedError.stackTrace = [expectedSyntaxError(token: includedToken, template: includedTemplate, description: reason).token!] - + let error = try expect(environment.render(template: template, context: ["target": "World"]), file: file, line: line, function: function).toThrow() as TemplateSyntaxError let reporter = SimpleErrorReporter() try expect(reporter.renderError(error), file: file, line: line, function: function) == reporter.renderError(expectedError) } - + $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") try expectError(reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.", - token: "include \"invalid-include.html\"", + token: """ + include "invalid-include.html" + """, includedToken: "target|unknown") } - + $0.it("reports runtime error in included template") { let filterExtension = Extension() filterExtension.registerFilter("unknown", filter: { (_: Any?) in throw TemplateSyntaxError("filter error") }) 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") try expectError(reason: "filter error", @@ -242,7 +248,7 @@ func testEnvironment() { } } - + $0.context("given base and child templates") { let path = Path(#file) + ".." + "fixtures" let loader = FileSystemLoader(paths: [path]) @@ -255,7 +261,7 @@ func testEnvironment() { childTemplate = nil baseTemplate = nil } - + func expectError(reason: String, childToken: String, baseToken: String?, file: String = #file, line: Int = #line, function: String = #function) throws { var expectedError = expectedSyntaxError(token: childToken, template: childTemplate, description: reason) @@ -271,12 +277,12 @@ func testEnvironment() { $0.it("reports syntax error in base template") { childTemplate = try environment.loadTemplate(name: "invalid-child-super.html") baseTemplate = try environment.loadTemplate(name: "invalid-base.html") - + try expectError(reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.", childToken: "extends \"invalid-base.html\"", baseToken: "target|unknown") } - + $0.it("reports runtime error in base template") { let filterExtension = Extension() filterExtension.registerFilter("unknown", filter: { (_: Any?) in @@ -291,16 +297,18 @@ func testEnvironment() { childToken: "block.super", baseToken: "target|unknown") } - + $0.it("reports syntax error in child template") { - childTemplate = Template(templateString: "{% extends \"base.html\" %}\n" + - "{% block body %}Child {{ target|unknown }}{% endblock %}", environment: environment, name: nil) - + childTemplate = Template(templateString: """ + {% extends "base.html" %} + {% block body %}Child {{ target|unknown }}{% endblock %} + """, environment: environment, name: nil) + try expectError(reason: "Unknown filter 'unknown'. Found similar filters: 'uppercase'.", childToken: "target|unknown", baseToken: nil) } - + $0.it("reports runtime error in child template") { let filterExtension = Extension() filterExtension.registerFilter("unknown", filter: { (_: Any?) in @@ -308,8 +316,10 @@ func testEnvironment() { }) environment.extensions += [filterExtension] - childTemplate = Template(templateString: "{% extends \"base.html\" %}\n" + - "{% block body %}Child {{ target|unknown }}{% endblock %}", environment: environment, name: nil) + childTemplate = Template(templateString: """ + {% extends "base.html" %} + {% block body %}Child {{ target|unknown }}{% endblock %} + """, environment: environment, name: nil) try expectError(reason: "filter error", childToken: "target|unknown", @@ -325,13 +335,13 @@ extension Expectation { @discardableResult func toThrow() throws -> T { var thrownError: Error? = nil - + do { _ = try expression() } catch { thrownError = error } - + if let thrownError = thrownError { if let thrownError = thrownError as? T { return thrownError diff --git a/Tests/StencilTests/FilterSpec.swift b/Tests/StencilTests/FilterSpec.swift index fe40fc4..d798632 100644 --- a/Tests/StencilTests/FilterSpec.swift +++ b/Tests/StencilTests/FilterSpec.swift @@ -23,7 +23,9 @@ func testFilter() { } $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() repeatExtension.registerFilter("repeat") { value, arguments in @@ -35,11 +37,15 @@ func testFilter() { } 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") { - 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() repeatExtension.registerFilter("repeat") { value, arguments in @@ -51,7 +57,9 @@ func testFilter() { } 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") { @@ -78,7 +86,9 @@ func testFilter() { } $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"]])) try expect(result) == "One, Two" } @@ -114,25 +124,33 @@ func testFilter() { $0.it("transforms a string to be capitalized") { let template = Template(templateString: "{{ names|capitalize }}") 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") { let template = Template(templateString: "{{ names|uppercase }}") 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") { let template = Template(templateString: "{{ names|lowercase }}") let result = try template.render(Context(dictionary: ["names": ["Kyle", "Kyle"]])) - try expect(result) == "[\"kyle\", \"kyle\"]" + try expect(result) == """ + ["kyle", "kyle"] + """ } } } 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") { let result = try template.render(Context(dictionary: ["name": "Kyle"])) @@ -145,7 +163,9 @@ func testFilter() { } $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: [:])) try expect(result) == "Hello World" } @@ -163,7 +183,9 @@ func testFilter() { } $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 user: [String: Any?] = ["name": nilName] let result = try template.render(Context(dictionary: ["user": user])) @@ -172,7 +194,9 @@ func testFilter() { } describe("join filter") { - let template = Template(templateString: "{{ value|join:\", \" }}") + let template = Template(templateString: """ + {{ value|join:", " }} + """) $0.it("joins a collection of strings") { let result = try template.render(Context(dictionary: ["value": ["One", "Two"]])) @@ -185,30 +209,42 @@ func testFilter() { } $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])) try expect(result) == "OnetrueTwo" } $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"]])) try expect(result) == "OneTwo" } } describe("split filter") { - let template = Template(templateString: "{{ value|split:\", \" }}") + let template = Template(templateString: """ + {{ value|split:", " }} + """) $0.it("split a string into array") { 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") { - let template = Template(templateString: "{{ value|split }}") + let template = Template(templateString: """ + {{ value|split }} + """) 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") { $0.it("indents content") { - let template = Template(templateString: "{{ value|indent:2 }}") - let result = try template.render(Context(dictionary: ["value": "One\nTwo"])) - try expect(result) == "One\n Two" + let template = Template(templateString: """ + {{ value|indent:2 }} + """) + let result = try template.render(Context(dictionary: ["value": """ + One + Two + """])) + try expect(result) == """ + One + Two + """ } $0.it("can indent with arbitrary character") { - let template = Template(templateString: "{{ value|indent:2,\"\t\" }}") - let result = try template.render(Context(dictionary: ["value": "One\nTwo"])) - try expect(result) == "One\n\t\tTwo" + let template = Template(templateString: """ + {{ value|indent:2,"\t" }} + """) + let result = try template.render(Context(dictionary: ["value": """ + One + Two + """])) + try expect(result) == """ + One + \t\tTwo + """ } $0.it("can indent first line") { - let template = Template(templateString: "{{ value|indent:2,\" \",true }}") - let result = try template.render(Context(dictionary: ["value": "One\nTwo"])) - try expect(result) == " One\n Two" + let template = Template(templateString: """ + {{ value|indent:2," ",true }} + """) + let result = try template.render(Context(dictionary: ["value": """ + One + Two + """])) + try expect(result) == """ + One + Two + """ } $0.it("does not indent empty lines") { - let template = Template(templateString: "{{ value|indent }}") - let result = try template.render(Context(dictionary: ["value": "One\n\n\nTwo\n\n"])) - try expect(result) == "One\n\n\n Two\n\n" + let template = Template(templateString: """ + {{ value|indent }} + """) + let result = try template.render(Context(dictionary: ["value": """ + One + + + Two + + + """])) + try expect(result) == """ + One + + + Two + + + """ } } } diff --git a/Tests/StencilTests/FilterTagSpec.swift b/Tests/StencilTests/FilterTagSpec.swift index 5d59fdc..4899531 100644 --- a/Tests/StencilTests/FilterTagSpec.swift +++ b/Tests/StencilTests/FilterTagSpec.swift @@ -27,7 +27,9 @@ func testFilterTag() { return ($0 as! String).components(separatedBy: $1[0] as! String) }) 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" } @@ -38,7 +40,9 @@ func testFilterTag() { return ($0 as! String).replacingOccurrences(of: $1[0] as! String, with: $1[1] as! String) }) 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" } } diff --git a/Tests/StencilTests/ForNodeSpec.swift b/Tests/StencilTests/ForNodeSpec.swift index 084dc51..f292a15 100644 --- a/Tests/StencilTests/ForNodeSpec.swift +++ b/Tests/StencilTests/ForNodeSpec.swift @@ -112,9 +112,11 @@ func testForNode() { } $0.it("can render a filter with spaces") { - let templateString = "{% for article in ars | default: a, b , articles %}" + - "- {{ article.title }} by {{ article.author }}.\n" + - "{% endfor %}\n" + let templateString = """ + {% for article in ars | default: a, b , articles %}\ + - {{ article.title }} by {{ article.author }}. + {% endfor %} + """ let context = Context(dictionary: [ "articles": [ @@ -126,54 +128,70 @@ func testForNode() { let template = Template(templateString: templateString) let result = try template.render(context) - let fixture = "" + - "- Migrating from OCUnit to XCTest by Kyle Fuller.\n" + - "- Memory Management with ARC by Kyle Fuller.\n" + - "\n" + try expect(result) == """ + - Migrating from OCUnit to XCTest by Kyle Fuller. + - Memory Management with ARC by Kyle Fuller. - try expect(result) == fixture + """ } $0.context("given array of tuples") { $0.it("can iterate over all tuple values") { - let templateString = "{% for first,second,third in tuples %}" + - "{{ first }}, {{ second }}, {{ third }}\n" + - "{% endfor %}\n" + let templateString = """ + {% for first,second,third in tuples %}\ + {{ first }}, {{ second }}, {{ third }} + {% endfor %} + """ let template = Template(templateString: templateString) let result = try template.render(context) - let fixture = "1, 2, 3\n4, 5, 6\n\n" - try expect(result) == fixture + try expect(result) == """ + 1, 2, 3 + 4, 5, 6 + + """ } $0.it("can iterate with less number of variables") { - let templateString = "{% for first,second in tuples %}" + - "{{ first }}, {{ second }}\n" + - "{% endfor %}\n" + let templateString = """ + {% for first,second in tuples %}\ + {{ first }}, {{ second }} + {% endfor %} + """ let template = Template(templateString: templateString) let result = try template.render(context) - let fixture = "1, 2\n4, 5\n\n" - try expect(result) == fixture + try expect(result) == """ + 1, 2 + 4, 5 + + """ } $0.it("can use _ to skip variables") { - let templateString = "{% for first,_,third in tuples %}" + - "{{ first }}, {{ third }}\n" + - "{% endfor %}\n" + let templateString = """ + {% for first,_,third in tuples %}\ + {{ first }}, {{ third }} + {% endfor %} + """ let template = Template(templateString: templateString) let result = try template.render(context) - let fixture = "1, 3\n4, 6\n\n" - try expect(result) == fixture + try expect(result) == """ + 1, 3 + 4, 6 + + """ } $0.it("throws when number of variables is more than number of tuple values") { - let templateString = "{% for key,value,smth in dict %}" + - "{% endfor %}\n" + let templateString = """ + {% for key,value,smth in dict %} + {% endfor %} + """ let template = Template(templateString: templateString) try expect(template.render(context)).toThrow() @@ -182,9 +200,11 @@ func testForNode() { } $0.it("can iterate over dictionary") { - let templateString = "{% for key, value in dict %}" + - "{{ key }}: {{ value }}," + - "{% endfor %}" + let templateString = """ + {% for key, value in dict %}\ + {{ key }}: {{ value }},\ + {% endfor %} + """ let template = Template(templateString: templateString) 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 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") { @@ -266,7 +290,11 @@ func testForNode() { let node = ForNode(resolvable: Variable("tuple"), loopVariables: ["label", "value"], nodes: nodes, emptyNodes: []) 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") { @@ -297,11 +325,16 @@ func testForNode() { VariableNode(variable: "value"), TextNode(text: "\n"), ] - + let node = ForNode(resolvable: Variable("class"), loopVariables: ["label", "value"], nodes: nodes, emptyNodes: []) 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") { @@ -313,7 +346,6 @@ func testForNode() { } - fileprivate struct Article { let title: String let author: String diff --git a/Tests/StencilTests/IncludeSpec.swift b/Tests/StencilTests/IncludeSpec.swift index a87dc85..cf51546 100644 --- a/Tests/StencilTests/IncludeSpec.swift +++ b/Tests/StencilTests/IncludeSpec.swift @@ -58,7 +58,9 @@ func testInclude() { } $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 value = try template.render(context) try expect(value) == "Hello World!" diff --git a/Tests/StencilTests/InheritenceSpec.swift b/Tests/StencilTests/InheritenceSpec.swift index a58107a..68ef597 100644 --- a/Tests/StencilTests/InheritenceSpec.swift +++ b/Tests/StencilTests/InheritenceSpec.swift @@ -11,17 +11,26 @@ func testInheritence() { $0.it("can inherit from another template") { 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") { 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") { 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 + """ } } } diff --git a/Tests/StencilTests/LexerSpec.swift b/Tests/StencilTests/LexerSpec.swift index 1babed9..fd3493d 100644 --- a/Tests/StencilTests/LexerSpec.swift +++ b/Tests/StencilTests/LexerSpec.swift @@ -69,15 +69,16 @@ func testLexer() { } $0.it("can tokenize with new lines") { - let templateString = - "My name is {%\n" + - " if name\n" + - " and\n" + - " name\n" + - "%}{{\n" + - "name\n" + - "}}{%\n" + - "endif %}." + let templateString = """ + My name is {% + if name + and + name + %}{{ + name + }}{% + endif %}. + """ let lexer = Lexer(templateString: templateString) diff --git a/Tests/StencilTests/StencilSpec.swift b/Tests/StencilTests/StencilSpec.swift index 099a407..137f5be 100644 --- a/Tests/StencilTests/StencilSpec.swift +++ b/Tests/StencilTests/StencilSpec.swift @@ -32,11 +32,13 @@ func testStencil() { $0.it("can render the README example") { - let templateString = "There are {{ articles.count }} articles.\n" + - "\n" + - "{% for article in articles %}" + - " - {{ article.title }} by {{ article.author }}.\n" + - "{% endfor %}\n" + let templateString = """ + There are {{ articles.count }} articles. + + {% for article in articles %}\ + - {{ article.title }} by {{ article.author }}. + {% endfor %} + """ let context = [ "articles": [ @@ -48,13 +50,13 @@ func testStencil() { let template = Template(templateString: templateString) let result = try template.render(context) - let fixture = "There are 2 articles.\n" + - "\n" + - " - Migrating from OCUnit to XCTest by Kyle Fuller.\n" + - " - Memory Management with ARC by Kyle Fuller.\n" + - "\n" + try expect(result) == """ + There are 2 articles. - 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") {