diff --git a/Stencil/Node.swift b/Stencil/Node.swift index b1622a2..7063fb6 100644 --- a/Stencil/Node.swift +++ b/Stencil/Node.swift @@ -16,6 +16,37 @@ public protocol Node { func render(context:Context) -> (String?, Error?) } +extension Array { + func map(block:((Element) -> (U?, Error?))) -> ([U]?, Error?) { + var results = [U]() + + for item in self { + let (result, error) = block(item) + + if let error = error { + return (nil, error) + } else if (result != nil) { + // let result = result exposing a bug in the Swift compier :( + results.append(result!) + } + } + + return (results, nil) + } +} + +public func render(nodes:[Node], context:Context) -> (String?, Error?) { + let result:(results:[String]?, error:Error?) = nodes.map { + return $0.render(context) + } + + if let result = result.0 { + return ("".join(result), nil) + } + + return (nil, result.1) +} + public class TextNode : Node { public let text:String diff --git a/StencilTests/NodeTests.swift b/StencilTests/NodeTests.swift index 7085de7..d3136dc 100644 --- a/StencilTests/NodeTests.swift +++ b/StencilTests/NodeTests.swift @@ -10,6 +10,19 @@ import Cocoa import XCTest import Stencil +class ErrorNodeError : Error { + var description: String { + return "Node Error" + } +} + +class ErrorNode : Node { + func render(context: Context) -> (String?, Error?) { + + return (nil, ErrorNodeError()) + } +} + class NodeTests: XCTestCase { var context:Context! @@ -45,3 +58,21 @@ class VariableNodeTests: NodeTests { XCTAssertEqual(result.0!, "27") } } + +class RenderNodeTests: NodeTests { + func testRenderingNodes() { + let nodes = [TextNode(text:"Hello "), VariableNode(variable: "name")] as [Node] + let (result:String?, error:Error?) = render(nodes, context) + + XCTAssertEqual(result!, "Hello Kyle") + XCTAssertTrue(error == nil) + } + + func testRenderingNodesWithFailure() { + let nodes = [TextNode(text:"Hello "), VariableNode(variable: "name"), ErrorNode()] as [Node] + let (result:String?, error:Error?) = render(nodes, context) + + XCTAssertEqual(error!.description, "Node Error") + XCTAssertTrue(result == nil) + } +}