Refactor render nodes to return a Result

This commit is contained in:
Kyle Fuller
2014-10-26 17:18:54 +00:00
parent 5a627999d5
commit d3b7e9ca0c
3 changed files with 31 additions and 28 deletions

View File

@@ -37,16 +37,16 @@ extension Array {
} }
} }
public func renderNodes(nodes:[Node], context:Context) -> (String?, Error?) { public func renderNodes(nodes:[Node], context:Context) -> Result {
let result:(results:[String]?, error:Error?) = nodes.map { let result:(results:[String]?, error:Error?) = nodes.map {
return $0.render(context) return $0.render(context)
} }
if let result = result.0 { if let result = result.0 {
return ("".join(result), nil) return .Success(string:"".join(result))
} }
return (nil, result.1) return .Error(error:result.1!)
} }
public class TextNode : Node { public class TextNode : Node {
@@ -178,26 +178,25 @@ public class ForNode : Node {
public func render(context: Context) -> (String?, Error?) { public func render(context: Context) -> (String?, Error?) {
let values = variable.resolve(context) as? [AnyObject] let values = variable.resolve(context) as? [AnyObject]
var result = "" var output = ""
if let values = values { if let values = values {
for item in values { for item in values {
context.push() context.push()
context[loopVariable] = item context[loopVariable] = item
let (string, error) = renderNodes(nodes, context) let result = renderNodes(nodes, context)
context.pop() context.pop()
if let error = error { switch result {
return (nil, error) case .Success(let string):
} output += string
case .Error(let error):
if let string = string { return (nil, error)
result += string
} }
} }
} }
return (result, nil) return (output, nil)
} }
} }
@@ -283,9 +282,14 @@ public class IfNode : Node {
} }
context.push() context.push()
let (string, error) = renderNodes(truthy ? trueNodes : falseNodes, context) let output = renderNodes(truthy ? trueNodes : falseNodes, context)
context.pop() context.pop()
return (string, error) switch output {
case .Success(let string):
return (string, nil)
case .Error(let error):
return (nil, error)
}
} }
} }

View File

@@ -39,13 +39,7 @@ public class Template {
public func render(context:Context) -> Result { public func render(context:Context) -> Result {
switch parser.parse() { switch parser.parse() {
case .Success(let nodes): case .Success(let nodes):
let (result, error) = renderNodes(nodes, context) return renderNodes(nodes, context)
if let result = result {
return .Success(string:result)
} else if let error = error {
return .Error(error:error)
}
return .Success(string:"")
case .Error(let error): case .Error(let error):
return .Error(error:error) return .Error(error:error)

View File

@@ -55,18 +55,23 @@ class VariableNodeTests: NodeTests {
class RenderNodeTests: NodeTests { class RenderNodeTests: NodeTests {
func testRenderingNodes() { func testRenderingNodes() {
let nodes = [TextNode(text:"Hello "), VariableNode(variable: "name")] as [Node] let nodes = [TextNode(text:"Hello "), VariableNode(variable: "name")] as [Node]
let (result:String?, error:Error?) = renderNodes(nodes, context) switch renderNodes(nodes, context) {
case .Success(let result):
XCTAssertEqual(result!, "Hello Kyle") XCTAssertEqual(result, "Hello Kyle")
XCTAssertTrue(error == nil) case .Error(let error):
XCTAssert(false, "Unexpected error")
}
} }
func testRenderingNodesWithFailure() { func testRenderingNodesWithFailure() {
let nodes = [TextNode(text:"Hello "), VariableNode(variable: "name"), ErrorNode()] as [Node] let nodes = [TextNode(text:"Hello "), VariableNode(variable: "name"), ErrorNode()] as [Node]
let (result:String?, error:Error?) = renderNodes(nodes, context)
XCTAssertEqual(error!.description, "Node Error") switch renderNodes(nodes, context) {
XCTAssertTrue(result == nil) case .Success(let result):
XCTAssert(false, "Unexpected success")
case .Error(let error):
XCTAssertEqual("\(error)", "Node Error")
}
} }
} }