added filter to apply dynamic filter

This commit is contained in:
Ilya Puchka
2018-03-22 23:14:30 +00:00
parent 39ed9aa753
commit 564ccb7af7
12 changed files with 129 additions and 70 deletions

View File

@@ -105,19 +105,19 @@ func testExpressions() {
$0.describe("expression parsing") {
$0.it("can parse a variable expression") {
let expression = try parseExpression(components: ["value"], tokenParser: parser)
let expression = try parser.compileExpression(components: ["value"])
try expect(expression.evaluate(context: Context())).to.beFalse()
try expect(expression.evaluate(context: Context(dictionary: ["value": true]))).to.beTrue()
}
$0.it("can parse a not expression") {
let expression = try parseExpression(components: ["not", "value"], tokenParser: parser)
let expression = try parser.compileExpression(components: ["not", "value"])
try expect(expression.evaluate(context: Context())).to.beTrue()
try expect(expression.evaluate(context: Context(dictionary: ["value": true]))).to.beFalse()
}
$0.describe("and expression") {
let expression = try! parseExpression(components: ["lhs", "and", "rhs"], tokenParser: parser)
let expression = try! parser.compileExpression(components: ["lhs", "and", "rhs"])
$0.it("evaluates to false with lhs false") {
try expect(expression.evaluate(context: Context(dictionary: ["lhs": false, "rhs": true]))).to.beFalse()
@@ -137,7 +137,7 @@ func testExpressions() {
}
$0.describe("or expression") {
let expression = try! parseExpression(components: ["lhs", "or", "rhs"], tokenParser: parser)
let expression = try! parser.compileExpression(components: ["lhs", "or", "rhs"])
$0.it("evaluates to true with lhs true") {
try expect(expression.evaluate(context: Context(dictionary: ["lhs": true, "rhs": false]))).to.beTrue()
@@ -157,7 +157,7 @@ func testExpressions() {
}
$0.describe("equality expression") {
let expression = try! parseExpression(components: ["lhs", "==", "rhs"], tokenParser: parser)
let expression = try! parser.compileExpression(components: ["lhs", "==", "rhs"])
$0.it("evaluates to true with equal lhs/rhs") {
try expect(expression.evaluate(context: Context(dictionary: ["lhs": "a", "rhs": "a"]))).to.beTrue()
@@ -193,7 +193,7 @@ func testExpressions() {
}
$0.describe("inequality expression") {
let expression = try! parseExpression(components: ["lhs", "!=", "rhs"], tokenParser: parser)
let expression = try! parser.compileExpression(components: ["lhs", "!=", "rhs"])
$0.it("evaluates to true with inequal lhs/rhs") {
try expect(expression.evaluate(context: Context(dictionary: ["lhs": "a", "rhs": "b"]))).to.beTrue()
@@ -205,7 +205,7 @@ func testExpressions() {
}
$0.describe("more than expression") {
let expression = try! parseExpression(components: ["lhs", ">", "rhs"], tokenParser: parser)
let expression = try! parser.compileExpression(components: ["lhs", ">", "rhs"])
$0.it("evaluates to true with lhs > rhs") {
try expect(expression.evaluate(context: Context(dictionary: ["lhs": 5.0, "rhs": 4]))).to.beTrue()
@@ -217,7 +217,7 @@ func testExpressions() {
}
$0.describe("more than equal expression") {
let expression = try! parseExpression(components: ["lhs", ">=", "rhs"], tokenParser: parser)
let expression = try! parser.compileExpression(components: ["lhs", ">=", "rhs"])
$0.it("evaluates to true with lhs == rhs") {
try expect(expression.evaluate(context: Context(dictionary: ["lhs": 5.0, "rhs": 5]))).to.beTrue()
@@ -229,7 +229,7 @@ func testExpressions() {
}
$0.describe("less than expression") {
let expression = try! parseExpression(components: ["lhs", "<", "rhs"], tokenParser: parser)
let expression = try! parser.compileExpression(components: ["lhs", "<", "rhs"])
$0.it("evaluates to true with lhs < rhs") {
try expect(expression.evaluate(context: Context(dictionary: ["lhs": 4, "rhs": 4.5]))).to.beTrue()
@@ -241,7 +241,7 @@ func testExpressions() {
}
$0.describe("less than equal expression") {
let expression = try! parseExpression(components: ["lhs", "<=", "rhs"], tokenParser: parser)
let expression = try! parser.compileExpression(components: ["lhs", "<=", "rhs"])
$0.it("evaluates to true with lhs == rhs") {
try expect(expression.evaluate(context: Context(dictionary: ["lhs": 5.0, "rhs": 5]))).to.beTrue()
@@ -253,7 +253,7 @@ func testExpressions() {
}
$0.describe("multiple expression") {
let expression = try! parseExpression(components: ["one", "or", "two", "and", "not", "three"], tokenParser: parser)
let expression = try! parser.compileExpression(components: ["one", "or", "two", "and", "not", "three"])
$0.it("evaluates to true with one") {
try expect(expression.evaluate(context: Context(dictionary: ["one": true]))).to.beTrue()
@@ -281,7 +281,7 @@ func testExpressions() {
}
$0.describe("in expression") {
let expression = try! parseExpression(components: ["lhs", "in", "rhs"], tokenParser: parser)
let expression = try! parser.compileExpression(components: ["lhs", "in", "rhs"])
$0.it("evaluates to true when rhs contains lhs") {
try expect(expression.evaluate(context: Context(dictionary: ["lhs": 1, "rhs": [1, 2, 3]]))).to.beTrue()

View File

@@ -3,14 +3,19 @@ import Spectre
func testFilter() {
func environmentWithFilter(_ name: String, closure: @escaping (Any?) throws -> Any?) -> Environment {
let filterExtension = Extension()
filterExtension.registerFilter(name, filter: closure)
return Environment(extensions: [filterExtension])
}
describe("template filters") {
let context: [String: Any] = ["name": "Kyle"]
$0.it("allows you to register a custom filter") {
let template = Template(templateString: "{{ name|repeat }}")
let repeatExtension = Extension()
repeatExtension.registerFilter("repeat") { (value: Any?) in
let env = environmentWithFilter("repeat") { (value: Any?) in
if let value = value as? String {
return "\(value) \(value)"
}
@@ -18,7 +23,7 @@ func testFilter() {
return nil
}
let result = try template.render(Context(dictionary: context, environment: Environment(extensions: [repeatExtension])))
let result = try template.render(Context(dictionary: context, environment: env))
try expect(result) == "Kyle Kyle"
}
@@ -39,19 +44,19 @@ func testFilter() {
}
$0.it("allows you to register a custom filter which accepts several arguments") {
let template = Template(templateString: "{{ name|repeat:'value\"1\"',\"value'2'\",'(key, value)' }}")
let repeatExtension = Extension()
repeatExtension.registerFilter("repeat") { value, arguments in
if !arguments.isEmpty {
return "\(value!) \(value!) with args 0: \(arguments[0]!), 1: \(arguments[1]!), 2: \(arguments[2]!)"
}
return nil
let template = Template(templateString: "{{ name|repeat:'value\"1\"',\"value'2'\",'(key, value)' }}")
let repeatExtension = Extension()
repeatExtension.registerFilter("repeat") { value, arguments in
if !arguments.isEmpty {
return "\(value!) \(value!) with args 0: \(arguments[0]!), 1: \(arguments[1]!), 2: \(arguments[2]!)"
}
let result = try template.render(Context(dictionary: context, environment: Environment(extensions: [repeatExtension])))
try expect(result) == "Kyle Kyle with args 0: value\"1\", 1: value'2', 2: (key, value)"
return nil
}
let result = try template.render(Context(dictionary: context, environment: Environment(extensions: [repeatExtension])))
try expect(result) == "Kyle Kyle with args 0: value\"1\", 1: value'2', 2: (key, value)"
}
$0.it("allows you to register a custom which throws") {
@@ -67,13 +72,11 @@ func testFilter() {
$0.it("allows you to override a default filter") {
let template = Template(templateString: "{{ name|join }}")
let repeatExtension = Extension()
repeatExtension.registerFilter("join") { (value: Any?) in
let env = environmentWithFilter("join") { (value: Any?) in
return "joined"
}
let result = try template.render(Context(dictionary: context, environment: Environment(extensions: [repeatExtension])))
let result = try template.render(Context(dictionary: context, environment: env))
try expect(result) == "joined"
}
@@ -212,7 +215,6 @@ func testFilter() {
}
}
describe("filter suggestion") {
$0.it("made for unknown filter") {
@@ -244,7 +246,6 @@ func testFilter() {
}
describe("indent filter") {
$0.it("indents content") {
let template = Template(templateString: "{{ value|indent:2 }}")
@@ -270,4 +271,27 @@ func testFilter() {
try expect(result) == "One\n\n\n Two\n\n"
}
}
describe("dynamic filter") {
$0.it("can apply dynamic filter") {
let template = Template(templateString: "{{ name|filter:somefilter }}")
let result = try template.render(Context(dictionary: ["name": "Jhon", "somefilter": "uppercase"]))
try expect(result) == "JHON"
}
$0.it("can apply dynamic filter on array") {
let template = Template(templateString: "{{ values|filter:joinfilter }}")
let result = try template.render(Context(dictionary: ["values": [1, 2, 3], "joinfilter": "join:\", \""]))
try expect(result) == "1, 2, 3"
}
$0.it("throws on unknown dynamic filter") {
let template = Template(templateString: "{{ values|filter:unknown }}")
let context = Context(dictionary: ["values": [1, 2, 3], "unknown": "absurd"])
try expect(try template.render(context)).toThrow()
}
}
}

View File

@@ -98,7 +98,8 @@ func testForNode() {
$0.it("renders the given nodes while filtering items using where expression") {
let nodes: [NodeType] = [VariableNode(variable: "item"), VariableNode(variable: "forloop.counter")]
let `where` = try parseExpression(components: ["item", ">", "1"], tokenParser: TokenParser(tokens: [], environment: Environment()))
let parser = TokenParser(tokens: [], environment: Environment())
let `where` = try parser.compileExpression(components: ["item", ">", "1"])
let node = ForNode(resolvable: Variable("items"), loopVariables: ["item"], nodes: nodes, emptyNodes: [], where: `where`)
try expect(try node.render(context)) == "2132"
}
@@ -106,7 +107,8 @@ func testForNode() {
$0.it("renders the given empty nodes when all items filtered out with where expression") {
let nodes: [NodeType] = [VariableNode(variable: "item")]
let emptyNodes: [NodeType] = [TextNode(text: "empty")]
let `where` = try parseExpression(components: ["item", "==", "0"], tokenParser: TokenParser(tokens: [], environment: Environment()))
let parser = TokenParser(tokens: [], environment: Environment())
let `where` = try parser.compileExpression(components: ["item", "==", "0"])
let node = ForNode(resolvable: Variable("emptyItems"), loopVariables: ["item"], nodes: nodes, emptyNodes: emptyNodes, where: `where`)
try expect(try node.render(context)) == "empty"
}

View File

@@ -200,7 +200,7 @@ func testVariable() {
}()
func makeVariable(_ token: String) throws -> RangeVariable? {
return try RangeVariable(token, parser: TokenParser(tokens: [], environment: context.environment))
return try RangeVariable(token, environment: context.environment)
}
$0.it("can resolve closed range as array") {