Add methods to render an array of nodes
This commit is contained in:
@@ -16,6 +16,37 @@ public protocol Node {
|
|||||||
func render(context:Context) -> (String?, Error?)
|
func render(context:Context) -> (String?, Error?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension Array {
|
||||||
|
func map<U>(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 class TextNode : Node {
|
||||||
public let text:String
|
public let text:String
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,19 @@ import Cocoa
|
|||||||
import XCTest
|
import XCTest
|
||||||
import Stencil
|
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 {
|
class NodeTests: XCTestCase {
|
||||||
var context:Context!
|
var context:Context!
|
||||||
|
|
||||||
@@ -45,3 +58,21 @@ class VariableNodeTests: NodeTests {
|
|||||||
XCTAssertEqual(result.0!, "27")
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user