Merge pull request #177 from kylef/iterating-tuple-arrays
Iterating array of tuples with more than two values
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
- Similar filters are suggested when unknown filter is used
|
- Similar filters are suggested when unknown filter is used
|
||||||
- Added `indent` filter
|
- Added `indent` filter
|
||||||
- Allow using new lines inside tags
|
- Allow using new lines inside tags
|
||||||
|
- Added support for iterating arrays of tuples
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
|
|||||||
@@ -53,25 +53,26 @@ class ForNode : NodeType {
|
|||||||
self.where = `where`
|
self.where = `where`
|
||||||
}
|
}
|
||||||
|
|
||||||
func push<Result>(value: Any, context: Context, closure: () throws -> (Result)) rethrows -> Result {
|
func push<Result>(value: Any, context: Context, closure: () throws -> (Result)) throws -> Result {
|
||||||
if loopVariables.isEmpty {
|
if loopVariables.isEmpty {
|
||||||
return try context.push() {
|
return try context.push() {
|
||||||
return try closure()
|
return try closure()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let value = value as? (Any, Any) {
|
let valueMirror = Mirror(reflecting: value)
|
||||||
let first = loopVariables[0]
|
if case .tuple? = valueMirror.displayStyle {
|
||||||
|
if loopVariables.count > Int(valueMirror.children.count) {
|
||||||
if loopVariables.count == 2 {
|
throw TemplateSyntaxError("Tuple '\(value)' has less values than loop variables")
|
||||||
let second = loopVariables[1]
|
|
||||||
|
|
||||||
return try context.push(dictionary: [first: value.0, second: value.1]) {
|
|
||||||
return try closure()
|
|
||||||
}
|
}
|
||||||
|
var variablesContext = [String: Any]()
|
||||||
|
valueMirror.children.prefix(loopVariables.count).enumerated().forEach({ (offset, element) in
|
||||||
|
if loopVariables[offset] != "_" {
|
||||||
|
variablesContext[loopVariables[offset]] = element.value
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return try context.push(dictionary: [first: value.0]) {
|
return try context.push(dictionary: variablesContext) {
|
||||||
return try closure()
|
return try closure()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ func testForNode() {
|
|||||||
"dict": [
|
"dict": [
|
||||||
"one": "I",
|
"one": "I",
|
||||||
"two": "II",
|
"two": "II",
|
||||||
]
|
],
|
||||||
|
"tuples": [(1, 2, 3), (4, 5, 6)]
|
||||||
])
|
])
|
||||||
|
|
||||||
$0.it("renders the given nodes for each item") {
|
$0.it("renders the given nodes for each item") {
|
||||||
@@ -127,6 +128,53 @@ func testForNode() {
|
|||||||
try expect(result) == fixture
|
try expect(result) == fixture
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$0.context("given array of tuples") {
|
||||||
|
$0.it("can iterate over all tuple values") {
|
||||||
|
let templateString = "{% for first,second,third in tuples %}" +
|
||||||
|
"{{ first }}, {{ second }}, {{ third }}\n" +
|
||||||
|
"{% endfor %}\n"
|
||||||
|
|
||||||
|
let template = Template(templateString: templateString)
|
||||||
|
let result = try template.render(context)
|
||||||
|
|
||||||
|
let fixture = "1, 2, 3\n4, 5, 6\n\n"
|
||||||
|
try expect(result) == fixture
|
||||||
|
}
|
||||||
|
|
||||||
|
$0.it("can iterate with less number of variables") {
|
||||||
|
let templateString = "{% for first,second in tuples %}" +
|
||||||
|
"{{ first }}, {{ second }}\n" +
|
||||||
|
"{% endfor %}\n"
|
||||||
|
|
||||||
|
let template = Template(templateString: templateString)
|
||||||
|
let result = try template.render(context)
|
||||||
|
|
||||||
|
let fixture = "1, 2\n4, 5\n\n"
|
||||||
|
try expect(result) == fixture
|
||||||
|
}
|
||||||
|
|
||||||
|
$0.it("can use _ to skip variables") {
|
||||||
|
let templateString = "{% for first,_,third in tuples %}" +
|
||||||
|
"{{ first }}, {{ third }}\n" +
|
||||||
|
"{% endfor %}\n"
|
||||||
|
|
||||||
|
let template = Template(templateString: templateString)
|
||||||
|
let result = try template.render(context)
|
||||||
|
|
||||||
|
let fixture = "1, 3\n4, 6\n\n"
|
||||||
|
try expect(result) == fixture
|
||||||
|
}
|
||||||
|
|
||||||
|
$0.it("throws when number of variables is more than number of tuple values") {
|
||||||
|
let templateString = "{% for key,value,smth in dict %}" +
|
||||||
|
"{% endfor %}\n"
|
||||||
|
|
||||||
|
let template = Template(templateString: templateString)
|
||||||
|
try expect(template.render(context)).toThrow()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
$0.it("can iterate over dictionary") {
|
$0.it("can iterate over dictionary") {
|
||||||
let templateString = "{% for key,value in dict %}" +
|
let templateString = "{% for key,value in dict %}" +
|
||||||
"{{ key }}: {{ value }}," +
|
"{{ key }}: {{ value }}," +
|
||||||
|
|||||||
Reference in New Issue
Block a user