Include node protocol along with text and variable nodes

This commit is contained in:
Kyle Fuller
2014-10-23 15:56:47 +01:00
parent e34084f3f0
commit 5af59ecb15
3 changed files with 128 additions and 0 deletions

View File

@@ -9,6 +9,8 @@
/* Begin PBXBuildFile section */
7725B3CB19F92B4F002CF74B /* VariableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7725B3CA19F92B4F002CF74B /* VariableTests.swift */; };
7725B3CD19F92B61002CF74B /* Variable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7725B3CC19F92B61002CF74B /* Variable.swift */; };
7725B3D319F9437F002CF74B /* NodeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7725B3D219F9437F002CF74B /* NodeTests.swift */; };
7725B3D519F9438F002CF74B /* Node.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7725B3D419F9438F002CF74B /* Node.swift */; };
77FAAE5819F91E480029DC5E /* Stencil.h in Headers */ = {isa = PBXBuildFile; fileRef = 77FAAE5719F91E480029DC5E /* Stencil.h */; settings = {ATTRIBUTES = (Public, ); }; };
77FAAE5E19F91E480029DC5E /* Stencil.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 77FAAE5219F91E480029DC5E /* Stencil.framework */; };
77FAAE6519F91E480029DC5E /* StencilTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77FAAE6419F91E480029DC5E /* StencilTests.swift */; };
@@ -29,6 +31,8 @@
/* Begin PBXFileReference section */
7725B3CA19F92B4F002CF74B /* VariableTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VariableTests.swift; sourceTree = "<group>"; };
7725B3CC19F92B61002CF74B /* Variable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Variable.swift; sourceTree = "<group>"; };
7725B3D219F9437F002CF74B /* NodeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NodeTests.swift; sourceTree = "<group>"; };
7725B3D419F9438F002CF74B /* Node.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Node.swift; sourceTree = "<group>"; };
77FAAE5219F91E480029DC5E /* Stencil.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Stencil.framework; sourceTree = BUILT_PRODUCTS_DIR; };
77FAAE5619F91E480029DC5E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
77FAAE5719F91E480029DC5E /* Stencil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Stencil.h; sourceTree = "<group>"; };
@@ -82,6 +86,7 @@
77FAAE5719F91E480029DC5E /* Stencil.h */,
77FAAE6E19F920750029DC5E /* Context.swift */,
7725B3CC19F92B61002CF74B /* Variable.swift */,
7725B3D419F9438F002CF74B /* Node.swift */,
77FAAE5519F91E480029DC5E /* Supporting Files */,
);
path = Stencil;
@@ -101,6 +106,7 @@
77FAAE6419F91E480029DC5E /* StencilTests.swift */,
77FAAE7019F9208C0029DC5E /* ContextTests.swift */,
7725B3CA19F92B4F002CF74B /* VariableTests.swift */,
7725B3D219F9437F002CF74B /* NodeTests.swift */,
77FAAE6219F91E480029DC5E /* Supporting Files */,
);
path = StencilTests;
@@ -223,6 +229,7 @@
files = (
77FAAE6F19F920750029DC5E /* Context.swift in Sources */,
7725B3CD19F92B61002CF74B /* Variable.swift in Sources */,
7725B3D519F9438F002CF74B /* Node.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -231,6 +238,7 @@
buildActionMask = 2147483647;
files = (
77FAAE6519F91E480029DC5E /* StencilTests.swift in Sources */,
7725B3D319F9437F002CF74B /* NodeTests.swift in Sources */,
7725B3CB19F92B4F002CF74B /* VariableTests.swift in Sources */,
77FAAE7119F9208C0029DC5E /* ContextTests.swift in Sources */,
);

61
Stencil/Node.swift Normal file
View File

@@ -0,0 +1,61 @@
//
// Node.swift
// Stencil
//
// Created by Kyle Fuller on 23/10/2014.
// Copyright (c) 2014 Cocode. All rights reserved.
//
import Foundation
public protocol Error : Printable {
}
public protocol Node : Equatable {
func render(context:Context) -> (String?, Error?)
}
public class TextNode : Node {
public let text:String
public init(text:String) {
self.text = text
}
public func render(context:Context) -> (String?, Error?) {
return (self.text, nil)
}
}
public func ==(lhs:TextNode, rhs:TextNode) -> Bool {
return true
}
public class VariableNode : Node {
let variable:Variable
public init(variable:Variable) {
self.variable = variable
}
public init(variable:String) {
self.variable = Variable(variable)
}
public func render(context:Context) -> (String?, Error?) {
let result:AnyObject? = variable.resolve(context)
if let result = result as? String {
return (result, nil)
} else if let result = result as? NSObject {
return (result.description, nil)
}
return (nil, nil)
}
}
public func ==(lhs:VariableNode, rhs:VariableNode) -> Bool {
return true
}

View File

@@ -0,0 +1,59 @@
//
// NodeTests.swift
// Stencil
//
// Created by Kyle Fuller on 23/10/2014.
// Copyright (c) 2014 Cocode. All rights reserved.
//
import Cocoa
import XCTest
import Stencil
class NodeTests: XCTestCase {
var context:Context!
override func setUp() {
context = Context(dictionary: [
"name": "Kyle",
"age": 27,
])
}
}
class TextNodeTests: NodeTests {
func testTextNodeResolvesText() {
let node = TextNode(text:"Hello World")
let result = node.render(context)
XCTAssertEqual(result.0!, "Hello World")
}
func testTwoIdenticalTextNodesAreEqual() {
let node1 = TextNode(text:"Hello World")
let node2 = TextNode(text:"Hello World")
XCTAssertEqual(node1, node2)
}
}
class VariableNodeTests: NodeTests {
func testVariableNodeResolvesVariable() {
let node = VariableNode(variable:Variable("name"))
let result = node.render(context)
XCTAssertEqual(result.0!, "Kyle")
}
func testVariableNodeResolvesNonStringVariable() {
let node = VariableNode(variable:Variable("age"))
let result = node.render(context)
XCTAssertEqual(result.0!, "27")
}
func testTwoIdenticalVariableNodesAreEqual() {
let node1 = VariableNode(variable:Variable("name"))
let node2 = VariableNode(variable:Variable("name"))
XCTAssertEqual(node1, node2)
}
}