feat: added in expression in if tag (#143)

This commit is contained in:
Ilya Puchka
2017-10-01 12:46:48 +02:00
committed by Kyle Fuller
parent 000e9a7f1a
commit 3180b26673
4 changed files with 49 additions and 0 deletions

View File

@@ -8,6 +8,7 @@
the for loop 0 indexed. the for loop 0 indexed.
- Introduces a new `DictionaryLoader` for loading templates from a Swift - Introduces a new `DictionaryLoader` for loading templates from a Swift
Dictionary. Dictionary.
- Added `in` expression in if tag for strings and arrays of hashable types
### Bug Fixes ### Bug Fixes

View File

@@ -85,6 +85,37 @@ final class NotExpression: Expression, PrefixOperator, CustomStringConvertible {
} }
} }
final class InExpression: Expression, InfixOperator, CustomStringConvertible {
let lhs: Expression
let rhs: Expression
init(lhs: Expression, rhs: Expression) {
self.lhs = lhs
self.rhs = rhs
}
var description: String {
return "(\(lhs) in \(rhs))"
}
func evaluate(context: Context) throws -> Bool {
if let lhs = lhs as? VariableExpression, let rhs = rhs as? VariableExpression {
let lhsValue = try lhs.variable.resolve(context)
let rhsValue = try rhs.variable.resolve(context)
if let lhs = lhsValue as? AnyHashable, let rhs = rhsValue as? [AnyHashable] {
return rhs.contains(lhs)
} else if let lhs = lhsValue as? String, let rhs = rhsValue as? String {
return rhs.contains(lhs)
} else if lhsValue == nil && rhsValue == nil {
return true
}
}
return false
}
}
final class OrExpression: Expression, InfixOperator, CustomStringConvertible { final class OrExpression: Expression, InfixOperator, CustomStringConvertible {
let lhs: Expression let lhs: Expression

View File

@@ -14,6 +14,7 @@ enum Operator {
let operators: [Operator] = [ let operators: [Operator] = [
.infix("in", 5, InExpression.self),
.infix("or", 6, OrExpression.self), .infix("or", 6, OrExpression.self),
.infix("and", 7, AndExpression.self), .infix("and", 7, AndExpression.self),
.prefix("not", 8, NotExpression.self), .prefix("not", 8, NotExpression.self),

View File

@@ -279,6 +279,22 @@ func testExpressions() {
try expect(expression.evaluate(context: Context())).to.beFalse() try expect(expression.evaluate(context: Context())).to.beFalse()
} }
} }
$0.describe("in expression") {
let expression = try! parseExpression(components: ["lhs", "in", "rhs"], tokenParser: parser)
$0.it("evaluates to true when rhs contains lhs") {
try expect(expression.evaluate(context: Context(dictionary: ["lhs": 1, "rhs": [1, 2, 3]]))).to.beTrue()
try expect(expression.evaluate(context: Context(dictionary: ["lhs": "a", "rhs": ["a", "b", "c"]]))).to.beTrue()
try expect(expression.evaluate(context: Context(dictionary: ["lhs": "a", "rhs": "abc"]))).to.beTrue()
}
$0.it("evaluates to false when rhs does not contain lhs") {
try expect(expression.evaluate(context: Context(dictionary: ["lhs": 1, "rhs": [2, 3, 4]]))).to.beFalse()
try expect(expression.evaluate(context: Context(dictionary: ["lhs": "a", "rhs": ["b", "c", "d"]]))).to.beFalse()
try expect(expression.evaluate(context: Context(dictionary: ["lhs": "a", "rhs": "bcd"]))).to.beFalse()
}
}
} }
} }
} }