diff --git a/Sources/HummingbirdMustache/Context.swift b/Sources/HummingbirdMustache/Context.swift
index 23852e3..9b758ae 100644
--- a/Sources/HummingbirdMustache/Context.swift
+++ b/Sources/HummingbirdMustache/Context.swift
@@ -18,6 +18,10 @@ struct HBMustacheContext: HBMustacheMethods {
return self.last
case "index":
return self.index
+ case "even":
+ return (self.index & 1) == 0
+ case "odd":
+ return (self.index & 1) == 1
default:
return nil
}
diff --git a/Sources/HummingbirdMustache/Method.swift b/Sources/HummingbirdMustache/Method.swift
index bb5d785..4bd8705 100644
--- a/Sources/HummingbirdMustache/Method.swift
+++ b/Sources/HummingbirdMustache/Method.swift
@@ -10,19 +10,39 @@ extension String: HBMustacheMethods {
return self.lowercased()
case "uppercased":
return self.uppercased()
+ case "reversed":
+ return self.reversed()
default:
return nil
}
}
}
+protocol HBComparableSequence {
+ func runComparableMethod(_ name: String) -> Any?
+}
+
extension Array: HBMustacheMethods {
func runMethod(_ name: String) -> Any? {
switch name {
case "reversed":
return self.reversed()
- case "enumerated":
- return self.enumerated()
+ case "count":
+ return self.count
+ default:
+ if let comparableSeq = self as? HBComparableSequence {
+ return comparableSeq.runComparableMethod(name)
+ }
+ return nil
+ }
+ }
+}
+
+extension Array: HBComparableSequence where Element: Comparable {
+ func runComparableMethod(_ name: String) -> Any? {
+ switch name {
+ case "sorted":
+ return self.sorted()
default:
return nil
}
@@ -32,8 +52,24 @@ extension Array: HBMustacheMethods {
extension Dictionary: HBMustacheMethods {
func runMethod(_ name: String) -> Any? {
switch name {
+ case "count":
+ return self.count
case "enumerated":
- return self.enumerated()
+ return self.map { (key: $0.key, value: $0.value) }
+ default:
+ if let comparableSeq = self as? HBComparableSequence {
+ return comparableSeq.runComparableMethod(name)
+ }
+ return nil
+ }
+ }
+}
+
+extension Dictionary: HBComparableSequence where Key: Comparable {
+ func runComparableMethod(_ name: String) -> Any? {
+ switch name {
+ case "sorted":
+ return self.map { (key: $0.key, value: $0.value) }.sorted { $0.key < $1.key }
default:
return nil
}
@@ -43,7 +79,7 @@ extension Dictionary: HBMustacheMethods {
extension Int: HBMustacheMethods {
func runMethod(_ name: String) -> Any? {
switch name {
- case "plus1":
+ case "plusone":
return self + 1
default:
return nil
diff --git a/Tests/HummingbirdMustacheTests/MethodTests.swift b/Tests/HummingbirdMustacheTests/MethodTests.swift
index ee7730f..505e8e2 100644
--- a/Tests/HummingbirdMustacheTests/MethodTests.swift
+++ b/Tests/HummingbirdMustacheTests/MethodTests.swift
@@ -26,9 +26,9 @@ final class MethodTests: XCTestCase {
""")
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
XCTAssertEqual(template.render(object), """
- first: resque
- hub
- last: rip
+ first: resque
+ hub
+ last: rip
""")
}
@@ -36,7 +36,7 @@ final class MethodTests: XCTestCase {
func testIndex() throws {
let template = try HBMustacheTemplate(string: """
{{#repo}}
- {{#index()}}{{plus1(.)}}) {{/}}{{ name }}
+ {{#index()}}{{plusone(.)}}{{/}}) {{ name }}
{{/repo}}
""")
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
@@ -48,6 +48,21 @@ final class MethodTests: XCTestCase {
""")
}
+ func testEvenOdd() throws {
+ let template = try HBMustacheTemplate(string: """
+ {{#repo}}
+ {{index()}}) {{#even()}}even {{/}}{{#odd()}}odd {{/}}{{ name }}
+ {{/repo}}
+ """)
+ let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
+ XCTAssertEqual(template.render(object), """
+ 0) even resque
+ 1) odd hub
+ 2) even rip
+
+ """)
+ }
+
func testReversed() throws {
let template = try HBMustacheTemplate(string: """
{{#reversed(repo)}}
@@ -63,10 +78,10 @@ final class MethodTests: XCTestCase {
""")
}
- func testArrayEnumerated() throws {
+ func testArrayIndex() throws {
let template = try HBMustacheTemplate(string: """
- {{#enumerated(repo)}}
- {{ offset }}) {{ element.name }}
+ {{#repo}}
+ {{ index() }}) {{ name }}
{{/repo}}
""")
let object: [String: Any] = ["repo": [["name": "resque"], ["name": "hub"], ["name": "rip"]]]
@@ -78,13 +93,37 @@ final class MethodTests: XCTestCase {
""")
}
+ func testArraySorted() throws {
+ let template = try HBMustacheTemplate(string: """
+ {{#sorted(repo)}}
+ {{ index() }}) {{ . }}
+ {{/repo}}
+ """)
+ let object: [String: Any] = ["repo": ["resque", "hub", "rip"]]
+ XCTAssertEqual(template.render(object), """
+ 0) hub
+ 1) resque
+ 2) rip
+
+ """)
+ }
+
func testDictionaryEnumerated() throws {
let template = try HBMustacheTemplate(string: """
- {{#enumerated(.)}}{{ element.key }} = {{ element.value }}{{/.}}
+ {{#enumerated(.)}}{{ key }} = {{ value }}{{/.}}
""")
let object: [String: Any] = ["one": 1, "two": 2]
let result = template.render(object)
XCTAssertTrue(result == "one = 1two = 2" || result == "two = 2one = 1")
}
+ func testDictionarySortedByKey() throws {
+ let template = try HBMustacheTemplate(string: """
+ {{#sorted(.)}}{{ key }} = {{ value }}{{/.}}
+ """)
+ let object: [String: Any] = ["one": 1, "two": 2, "three": 3]
+ let result = template.render(object)
+ XCTAssertEqual(result, "one = 1three = 3two = 2")
+ }
+
}