feat(if): Support >, >=, < and <= operators

Closes #52
This commit is contained in:
Kyle Fuller
2016-11-28 18:17:01 +00:00
parent ab6f1a032d
commit c59b263446
5 changed files with 179 additions and 1 deletions

View File

@@ -21,7 +21,7 @@
values of Swift structures and classes inside a Context.
- If tags can now use prefix and infix operators such as `not`, `and`, `or`,
`==`, and `!=`.
`==`, `!=`, `>`, `>=`, `<` and `<=`.
```html+django
{% if one or two and not three %}

View File

@@ -170,6 +170,88 @@ class EqualityExpression: Expression, InfixOperator, CustomStringConvertible {
}
class NumericExpression: Expression, InfixOperator, CustomStringConvertible {
let lhs: Expression
let rhs: Expression
required init(lhs: Expression, rhs: Expression) {
self.lhs = lhs
self.rhs = rhs
}
var description: String {
return "(\(lhs) \(op) \(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, let rhs = rhsValue {
if let lhs = toNumber(value: lhs), let rhs = toNumber(value: rhs) {
return compare(lhs: lhs, rhs: rhs)
}
}
}
return false
}
var op: String {
return ""
}
func compare(lhs: Float80, rhs: Float80) -> Bool {
return false
}
}
class MoreThanExpression: NumericExpression {
override var op: String {
return ">"
}
override func compare(lhs: Float80, rhs: Float80) -> Bool {
return lhs > rhs
}
}
class MoreThanEqualExpression: NumericExpression {
override var op: String {
return ">="
}
override func compare(lhs: Float80, rhs: Float80) -> Bool {
return lhs >= rhs
}
}
class LessThanExpression: NumericExpression {
override var op: String {
return "<"
}
override func compare(lhs: Float80, rhs: Float80) -> Bool {
return lhs < rhs
}
}
class LessThanEqualExpression: NumericExpression {
override var op: String {
return "<="
}
override func compare(lhs: Float80, rhs: Float80) -> Bool {
return lhs <= rhs
}
}
class InequalityExpression: EqualityExpression {
override var description: String {
return "(\(lhs) != \(rhs))"

View File

@@ -19,6 +19,10 @@ let operators: [Operator] = [
.prefix("not", 8, NotExpression.self),
.infix("==", 10, EqualityExpression.self),
.infix("!=", 10, InequalityExpression.self),
.infix(">", 10, MoreThanExpression.self),
.infix(">=", 10, MoreThanEqualExpression.self),
.infix("<", 10, LessThanExpression.self),
.infix("<=", 10, LessThanEqualExpression.self),
]

View File

@@ -202,6 +202,54 @@ func testExpressions() {
}
}
$0.describe("more than expression") {
let expression = try! parseExpression(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()
}
$0.it("evaluates to false with lhs == rhs") {
try expect(expression.evaluate(context: Context(dictionary: ["lhs": 5.0, "rhs": 5.0]))).to.beFalse()
}
}
$0.describe("more than equal expression") {
let expression = try! parseExpression(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()
}
$0.it("evaluates to false with lhs < rhs") {
try expect(expression.evaluate(context: Context(dictionary: ["lhs": 5.0, "rhs": 5.1]))).to.beFalse()
}
}
$0.describe("less than expression") {
let expression = try! parseExpression(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()
}
$0.it("evaluates to false with lhs == rhs") {
try expect(expression.evaluate(context: Context(dictionary: ["lhs": 5.0, "rhs": 5.0]))).to.beFalse()
}
}
$0.describe("less than equal expression") {
let expression = try! parseExpression(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()
}
$0.it("evaluates to false with lhs > rhs") {
try expect(expression.evaluate(context: Context(dictionary: ["lhs": 5.1, "rhs": 5.0]))).to.beFalse()
}
}
$0.describe("multiple expression") {
let expression = try! parseExpression(components: ["one", "or", "two", "and", "not", "three"])

View File

@@ -117,6 +117,50 @@ Will be treated as:
.. note:: The inequality operator only supports numerical, string and boolean types.
``<`` operator
"""""""""""""""
.. code-block:: html+django
{% if value < other_value %}
value is less than other_value
{% endif %}
.. note:: The less than operator only supports numerical types.
``<=`` operator
"""""""""""""""
.. code-block:: html+django
{% if value <= other_value %}
value is less than or equal to other_value
{% endif %}
.. note:: The less than equal operator only supports numerical types.
``>`` operator
"""""""""""""""
.. code-block:: html+django
{% if value > other_value %}
value is more than other_value
{% endif %}
.. note:: The more than operator only supports numerical types.
``>=`` operator
"""""""""""""""
.. code-block:: html+django
{% if value >= other_value %}
value is more than or equal to other_value
{% endif %}
.. note:: The more than equal operator only supports numerical types.
``ifnot``
~~~~~~~~~