@@ -154,3 +154,66 @@ public class ForNode : Node {
|
|||||||
return (result, nil)
|
return (result, nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class IfNode : Node {
|
||||||
|
public let variable:Variable
|
||||||
|
public let trueNodes:[Node]
|
||||||
|
public let falseNodes:[Node]
|
||||||
|
|
||||||
|
public class func parse(parser:TokenParser, token:Token) -> Node {
|
||||||
|
let variable = token.components()[1]
|
||||||
|
|
||||||
|
let trueNodes = parser.parse(until(["endif", "else"]))
|
||||||
|
var falseNodes = [Node]()
|
||||||
|
|
||||||
|
if let token = parser.nextToken() {
|
||||||
|
if token.contents == "else" {
|
||||||
|
falseNodes = parser.parse(until(["endif"]))
|
||||||
|
parser.nextToken()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return IfNode(variable: variable, trueNodes: trueNodes, falseNodes: falseNodes)
|
||||||
|
}
|
||||||
|
|
||||||
|
public class func parse_ifnot(parser:TokenParser, token:Token) -> Node {
|
||||||
|
let variable = token.components()[1]
|
||||||
|
|
||||||
|
let falseNodes = parser.parse(until(["endif", "else"]))
|
||||||
|
var trueNodes = [Node]()
|
||||||
|
|
||||||
|
if let token = parser.nextToken() {
|
||||||
|
if token.contents == "else" {
|
||||||
|
trueNodes = parser.parse(until(["endif"]))
|
||||||
|
parser.nextToken()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return IfNode(variable: variable, trueNodes: trueNodes, falseNodes: falseNodes)
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(variable:String, trueNodes:[Node], falseNodes:[Node]) {
|
||||||
|
self.variable = Variable(variable)
|
||||||
|
self.trueNodes = trueNodes
|
||||||
|
self.falseNodes = falseNodes
|
||||||
|
}
|
||||||
|
|
||||||
|
public func render(context: Context) -> (String?, Error?) {
|
||||||
|
let result: AnyObject? = variable.resolve(context)
|
||||||
|
var truthy = false
|
||||||
|
|
||||||
|
if let result = result as? [AnyObject] {
|
||||||
|
if result.count > 0 {
|
||||||
|
truthy = true
|
||||||
|
}
|
||||||
|
} else if let result: AnyObject = result {
|
||||||
|
truthy = true
|
||||||
|
}
|
||||||
|
|
||||||
|
context.push()
|
||||||
|
let (string, error) = renderNodes(truthy ? trueNodes : falseNodes, context)
|
||||||
|
context.pop()
|
||||||
|
|
||||||
|
return (string, error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ public class TokenParser {
|
|||||||
self.tokens = tokens
|
self.tokens = tokens
|
||||||
tags["for"] = ForNode.parse
|
tags["for"] = ForNode.parse
|
||||||
tags["now"] = NowNode.parse
|
tags["now"] = NowNode.parse
|
||||||
|
tags["if"] = IfNode.parse
|
||||||
|
tags["ifnot"] = IfNode.parse_ifnot
|
||||||
}
|
}
|
||||||
|
|
||||||
public func parse() -> [Node] {
|
public func parse() -> [Node] {
|
||||||
|
|||||||
@@ -86,3 +86,71 @@ class ForNodeTests: NodeTests {
|
|||||||
XCTAssertEqual(result.0!, "123")
|
XCTAssertEqual(result.0!, "123")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class IfNodeTests: NodeTests {
|
||||||
|
|
||||||
|
// MARK: Parsing
|
||||||
|
|
||||||
|
func testParseIf() {
|
||||||
|
let tokens = [
|
||||||
|
Token.Block(value: "if value"),
|
||||||
|
Token.Text(value: "true"),
|
||||||
|
Token.Block(value: "else"),
|
||||||
|
Token.Text(value: "false"),
|
||||||
|
Token.Block(value: "endif")
|
||||||
|
]
|
||||||
|
|
||||||
|
let parser = TokenParser(tokens: tokens)
|
||||||
|
let nodes = parser.parse()
|
||||||
|
let node = nodes.first! as IfNode
|
||||||
|
let trueNode = node.trueNodes.first! as TextNode
|
||||||
|
let falseNode = node.falseNodes.first! as TextNode
|
||||||
|
|
||||||
|
XCTAssertEqual(nodes.count, 1)
|
||||||
|
XCTAssertEqual(node.variable.variable, "value")
|
||||||
|
XCTAssertEqual(node.trueNodes.count, 1)
|
||||||
|
XCTAssertEqual(trueNode.text, "true")
|
||||||
|
XCTAssertEqual(node.falseNodes.count, 1)
|
||||||
|
XCTAssertEqual(falseNode.text, "false")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testParseIfNot() {
|
||||||
|
let tokens = [
|
||||||
|
Token.Block(value: "ifnot value"),
|
||||||
|
Token.Text(value: "false"),
|
||||||
|
Token.Block(value: "else"),
|
||||||
|
Token.Text(value: "true"),
|
||||||
|
Token.Block(value: "endif")
|
||||||
|
]
|
||||||
|
|
||||||
|
let parser = TokenParser(tokens: tokens)
|
||||||
|
let nodes = parser.parse()
|
||||||
|
let node = nodes.first! as IfNode
|
||||||
|
let trueNode = node.trueNodes.first! as TextNode
|
||||||
|
let falseNode = node.falseNodes.first! as TextNode
|
||||||
|
|
||||||
|
XCTAssertEqual(nodes.count, 1)
|
||||||
|
XCTAssertEqual(node.variable.variable, "value")
|
||||||
|
XCTAssertEqual(node.trueNodes.count, 1)
|
||||||
|
XCTAssertEqual(trueNode.text, "true")
|
||||||
|
XCTAssertEqual(node.falseNodes.count, 1)
|
||||||
|
XCTAssertEqual(falseNode.text, "false")
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Rendering
|
||||||
|
|
||||||
|
func testIfNodeRenderTruth() {
|
||||||
|
let node = IfNode(variable: "items", trueNodes: [TextNode(text: "true")], falseNodes: [TextNode(text: "false")])
|
||||||
|
let result = node.render(context)
|
||||||
|
|
||||||
|
XCTAssertEqual(result.0!, "true")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testIfNodeRenderFalse() {
|
||||||
|
let node = IfNode(variable: "unknown", trueNodes: [TextNode(text: "true")], falseNodes: [TextNode(text: "false")])
|
||||||
|
let result = node.render(context)
|
||||||
|
|
||||||
|
XCTAssertEqual(result.0!, "false")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user