Merge pull request #40 from njdehoog/array_any
Cast ForNode values to Array<Any>
This commit is contained in:
@@ -157,7 +157,7 @@ public class ForNode : NodeType {
|
|||||||
public func render(context: Context) throws -> String {
|
public func render(context: Context) throws -> String {
|
||||||
let values = try variable.resolve(context)
|
let values = try variable.resolve(context)
|
||||||
|
|
||||||
if let values = values as? NSArray where values.count > 0 {
|
if let values = values as? [Any] where values.count > 0 {
|
||||||
return try values.map { item in
|
return try values.map { item in
|
||||||
try context.push([loopVariable: item]) {
|
try context.push([loopVariable: item]) {
|
||||||
try renderNodes(nodes, context)
|
try renderNodes(nodes, context)
|
||||||
@@ -232,10 +232,10 @@ public class IfNode : NodeType {
|
|||||||
let result = try variable.resolve(context)
|
let result = try variable.resolve(context)
|
||||||
var truthy = false
|
var truthy = false
|
||||||
|
|
||||||
if let result = result as? NSArray {
|
if let result = result as? [Any] {
|
||||||
if result.count > 0 {
|
truthy = !result.isEmpty
|
||||||
truthy = true
|
} else if let result = result as? [String:Any] {
|
||||||
}
|
truthy = !result.isEmpty
|
||||||
} else if result != nil {
|
} else if result != nil {
|
||||||
truthy = true
|
truthy = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,11 +58,9 @@ public struct Variable : Equatable, Resolvable {
|
|||||||
for bit in lookup() {
|
for bit in lookup() {
|
||||||
if let context = current as? Context {
|
if let context = current as? Context {
|
||||||
current = context[bit]
|
current = context[bit]
|
||||||
} else if let dictionary = current as? [String: Any] {
|
} else if let dictionary = resolveDictionary(current) {
|
||||||
current = dictionary[bit]
|
current = dictionary[bit]
|
||||||
} else if let dictionary = current as? [String: AnyObject] {
|
} else if let array = resolveArray(current) {
|
||||||
current = dictionary[bit]
|
|
||||||
} else if let array = current as? [Any] {
|
|
||||||
if let index = Int(bit) {
|
if let index = Int(bit) {
|
||||||
current = array[index]
|
current = array[index]
|
||||||
} else if bit == "first" {
|
} else if bit == "first" {
|
||||||
@@ -72,27 +70,66 @@ public struct Variable : Equatable, Resolvable {
|
|||||||
} else if bit == "count" {
|
} else if bit == "count" {
|
||||||
current = array.count
|
current = array.count
|
||||||
}
|
}
|
||||||
} else if let array = current as? NSArray {
|
} else if let object = current as? NSObject { // NSKeyValueCoding
|
||||||
if let index = Int(bit) {
|
|
||||||
current = array[index]
|
|
||||||
} else if bit == "first" {
|
|
||||||
current = array.firstObject
|
|
||||||
} else if bit == "last" {
|
|
||||||
current = array.lastObject
|
|
||||||
} else if bit == "count" {
|
|
||||||
current = array.count
|
|
||||||
}
|
|
||||||
} else if let object = current as? NSObject {
|
|
||||||
current = object.valueForKey(bit)
|
current = object.valueForKey(bit)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return current
|
return normalize(current)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func ==(lhs: Variable, rhs: Variable) -> Bool {
|
public func ==(lhs: Variable, rhs: Variable) -> Bool {
|
||||||
return lhs.variable == rhs.variable
|
return lhs.variable == rhs.variable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func resolveDictionary(current: Any?) -> [String: Any]? {
|
||||||
|
switch current {
|
||||||
|
case let dictionary as [String: Any]:
|
||||||
|
return dictionary
|
||||||
|
case let dictionary as [String: AnyObject]:
|
||||||
|
var result: [String: Any] = [:]
|
||||||
|
for (k, v) in dictionary {
|
||||||
|
result[k] = v as Any
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
case let dictionary as NSDictionary:
|
||||||
|
var result: [String: Any] = [:]
|
||||||
|
for (k, v) in dictionary {
|
||||||
|
if let k = k as? String {
|
||||||
|
result[k] = v as Any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveArray(current: Any?) -> [Any]? {
|
||||||
|
switch current {
|
||||||
|
case let array as [Any]:
|
||||||
|
return array
|
||||||
|
case let array as [AnyObject]:
|
||||||
|
return array.map { $0 as Any }
|
||||||
|
case let array as NSArray:
|
||||||
|
return array.map { $0 as Any }
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func normalize(current: Any?) -> Any? {
|
||||||
|
if let array = resolveArray(current) {
|
||||||
|
return array
|
||||||
|
}
|
||||||
|
|
||||||
|
if let dictionary = resolveDictionary(current) {
|
||||||
|
return dictionary
|
||||||
|
}
|
||||||
|
|
||||||
|
return current
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import Spectre
|
import Spectre
|
||||||
import Stencil
|
import Stencil
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
describe("ForNode") {
|
describe("ForNode") {
|
||||||
@@ -20,4 +21,24 @@ describe("ForNode") {
|
|||||||
let node = ForNode(variable: "emptyItems", loopVariable: "item", nodes: nodes, emptyNodes: emptyNodes)
|
let node = ForNode(variable: "emptyItems", loopVariable: "item", nodes: nodes, emptyNodes: emptyNodes)
|
||||||
try expect(try node.render(context)) == "empty"
|
try expect(try node.render(context)) == "empty"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$0.it("renders a context variable of type Array<Any>") {
|
||||||
|
let any_context = Context(dictionary: [
|
||||||
|
"items": ([1, 2, 3] as [Any])
|
||||||
|
])
|
||||||
|
|
||||||
|
let nodes: [NodeType] = [VariableNode(variable: "item")]
|
||||||
|
let node = ForNode(variable: "items", loopVariable: "item", nodes: nodes, emptyNodes: [])
|
||||||
|
try expect(try node.render(any_context)) == "123"
|
||||||
|
}
|
||||||
|
|
||||||
|
$0.it("renders a context variable of type NSArray") {
|
||||||
|
let nsarray_context = Context(dictionary: [
|
||||||
|
"items": NSArray(array: [1, 2, 3])
|
||||||
|
])
|
||||||
|
|
||||||
|
let nodes: [NodeType] = [VariableNode(variable: "item")]
|
||||||
|
let node = ForNode(variable: "items", loopVariable: "item", nodes: nodes, emptyNodes: [])
|
||||||
|
try expect(try node.render(nsarray_context)) == "123"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,5 +96,18 @@ describe("IfNode") {
|
|||||||
let node = IfNode(variable: "items", trueNodes: [TextNode(text: "true")], falseNodes: [TextNode(text: "false")])
|
let node = IfNode(variable: "items", trueNodes: [TextNode(text: "true")], falseNodes: [TextNode(text: "false")])
|
||||||
try expect(try node.render(arrayContext)) == "false"
|
try expect(try node.render(arrayContext)) == "false"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$0.it("renders the false when dictionary expression is empty") {
|
||||||
|
let emptyItems = [String:AnyObject]()
|
||||||
|
let arrayContext = Context(dictionary: ["items": emptyItems])
|
||||||
|
let node = IfNode(variable: "items", trueNodes: [TextNode(text: "true")], falseNodes: [TextNode(text: "false")])
|
||||||
|
try expect(try node.render(arrayContext)) == "false"
|
||||||
|
}
|
||||||
|
|
||||||
|
$0.it("renders the false when Array<Any> variable is empty") {
|
||||||
|
let arrayContext = Context(dictionary: ["items": ([] as [Any])])
|
||||||
|
let node = IfNode(variable: "items", trueNodes: [TextNode(text: "true")], falseNodes: [TextNode(text: "false")])
|
||||||
|
try expect(try node.render(arrayContext)) == "false"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user