diff --git a/Stencil/Node.swift b/Stencil/Node.swift index c8c8293..ab3e984 100644 --- a/Stencil/Node.swift +++ b/Stencil/Node.swift @@ -47,7 +47,7 @@ public class TextNode : NodeType { } public protocol Resolvable { - func resolve(context: Context) -> Any? + func resolve(context: Context) throws -> Any? } public class VariableNode : NodeType { @@ -62,7 +62,7 @@ public class VariableNode : NodeType { } public func render(context: Context) throws -> String { - let result = variable.resolve(context) + let result = try variable.resolve(context) if let result = result as? String { return result @@ -99,7 +99,7 @@ public class NowNode : NodeType { public func render(context: Context) throws -> String { let date = NSDate() - let format = self.format.resolve(context) + let format = try self.format.resolve(context) var formatter:NSDateFormatter? if let format = format as? NSDateFormatter { @@ -154,7 +154,7 @@ public class ForNode : NodeType { } public func render(context: Context) throws -> String { - let values = variable.resolve(context) + let values = try variable.resolve(context) if let values = values as? NSArray { return try values.map { item in context.push() @@ -227,7 +227,7 @@ public class IfNode : NodeType { } public func render(context: Context) throws -> String { - let result = variable.resolve(context) + let result = try variable.resolve(context) var truthy = false if let result = result as? [AnyObject] { diff --git a/Stencil/Parser.swift b/Stencil/Parser.swift index af94ae5..bbb3886 100644 --- a/Stencil/Parser.swift +++ b/Stencil/Parser.swift @@ -10,7 +10,7 @@ public func until(tags:[String])(parser:TokenParser, token:Token) -> Bool { return false } -public typealias Filter = Any? -> Any? +public typealias Filter = Any? throws -> Any? /// A class for parsing an array of tokens and converts them into a collection of Node's public class TokenParser { diff --git a/Stencil/Variable.swift b/Stencil/Variable.swift index b726399..d6a14f7 100644 --- a/Stencil/Variable.swift +++ b/Stencil/Variable.swift @@ -24,11 +24,11 @@ class FilterExpression : Resolvable { } } - func resolve(context: Context) -> Any? { - let result = variable.resolve(context) + func resolve(context: Context) throws -> Any? { + let result = try variable.resolve(context) - return filters.reduce(result) { x, y in - return y(x) + return try filters.reduce(result) { x, y in + return try y(x) } } } @@ -47,7 +47,7 @@ public struct Variable : Equatable, Resolvable { } /// Resolve the variable in the given context - public func resolve(context:Context) -> Any? { + public func resolve(context:Context) throws -> Any? { var current: Any? = context if (variable.hasPrefix("'") && variable.hasSuffix("'")) || (variable.hasPrefix("\"") && variable.hasSuffix("\"")) { diff --git a/StencilSpecs/FilterSpec.swift b/StencilSpecs/FilterSpec.swift index fb7ef6f..3f21bfa 100644 --- a/StencilSpecs/FilterSpec.swift +++ b/StencilSpecs/FilterSpec.swift @@ -4,9 +4,9 @@ import Stencil describe("template filters") { let context = Context(dictionary: ["name": "Kyle"]) - let template = Template(templateString: "{{ name|repeat }}") $0.it("allows you to register a custom filter") { + let template = Template(templateString: "{{ name|repeat }}") template.parser.registerFilter("repeat") { value in if let value = value as? String { return "\(value) \(value)" @@ -18,6 +18,15 @@ describe("template filters") { let result = try template.render(context) try expect(result) == "Kyle Kyle" } + + $0.it("allows you to register a custom filter") { + let template = Template(templateString: "{{ name|repeat }}") + template.parser.registerFilter("repeat") { value in + throw TemplateSyntaxError("No Repeat") + } + + try expect(try template.render(context)).toThrow(TemplateSyntaxError("No Repeat")) + } } diff --git a/StencilSpecs/VariableSpec.swift b/StencilSpecs/VariableSpec.swift index c4c9a38..f021d90 100644 --- a/StencilSpecs/VariableSpec.swift +++ b/StencilSpecs/VariableSpec.swift @@ -20,49 +20,49 @@ describe("Variable") { $0.it("can resolve a string literal with double quotes") { let variable = Variable("\"name\"") - let result = variable.resolve(context) as? String + let result = try variable.resolve(context) as? String try expect(result) == "name" } $0.it("can resolve a string literal with single quotes") { let variable = Variable("'name'") - let result = variable.resolve(context) as? String + let result = try variable.resolve(context) as? String try expect(result) == "name" } $0.it("can resolve a string variable") { let variable = Variable("name") - let result = variable.resolve(context) as? String + let result = try variable.resolve(context) as? String try expect(result) == "Kyle" } $0.it("can resolve an item from a dictionary") { let variable = Variable("profiles.github") - let result = variable.resolve(context) as? String + let result = try variable.resolve(context) as? String try expect(result) == "kylef" } $0.it("can resolve an item from an array via it's index") { let variable = Variable("contacts.0") - let result = variable.resolve(context) as? String + let result = try variable.resolve(context) as? String try expect(result) == "Katie" } $0.it("can resolve the first item from an array") { let variable = Variable("contacts.first") - let result = variable.resolve(context) as? String + let result = try variable.resolve(context) as? String try expect(result) == "Katie" } $0.it("can resolve the last item from an array") { let variable = Variable("contacts.last") - let result = variable.resolve(context) as? String + let result = try variable.resolve(context) as? String try expect(result) == "Carlton" } $0.it("can resolve a value via KVO") { let variable = Variable("object.title") - let result = variable.resolve(context) as? String + let result = try variable.resolve(context) as? String try expect(result) == "Hello World" } }