From ab6f1a032d6324f7ad1bdb105787988a4f71fa65 Mon Sep 17 00:00:00 2001 From: Kyle Fuller Date: Mon, 28 Nov 2016 17:56:49 +0000 Subject: [PATCH] feat(if): Support inequality operator --- CHANGELOG.md | 4 ++-- Sources/Expression.swift | 15 +++++++++++++-- Sources/IfTag.swift | 1 + Tests/StencilTests/ExpressionSpec.swift | 14 +++++++++++++- docs/builtins.rst | 11 +++++++++++ 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 167de4c..cf026f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,8 +20,8 @@ - Variable lookup now supports introspection of Swift types. You can now lookup values of Swift structures and classes inside a Context. -- If tags can now use prefix and infix operators such as `not`, `and`, `or` and - `==`. +- If tags can now use prefix and infix operators such as `not`, `and`, `or`, + `==`, and `!=`. ```html+django {% if one or two and not three %} diff --git a/Sources/Expression.swift b/Sources/Expression.swift index b935556..926b8c2 100644 --- a/Sources/Expression.swift +++ b/Sources/Expression.swift @@ -134,11 +134,11 @@ final class AndExpression: Expression, InfixOperator, CustomStringConvertible { } -final class EqualityExpression: Expression, InfixOperator, CustomStringConvertible { +class EqualityExpression: Expression, InfixOperator, CustomStringConvertible { let lhs: Expression let rhs: Expression - init(lhs: Expression, rhs: Expression) { + required init(lhs: Expression, rhs: Expression) { self.lhs = lhs self.rhs = rhs } @@ -170,6 +170,17 @@ final class EqualityExpression: Expression, InfixOperator, CustomStringConvertib } +class InequalityExpression: EqualityExpression { + override var description: String { + return "(\(lhs) != \(rhs))" + } + + override func evaluate(context: Context) throws -> Bool { + return try !super.evaluate(context: context) + } +} + + func toNumber(value: Any) -> Float80? { if let value = value as? Float { return Float80(value) diff --git a/Sources/IfTag.swift b/Sources/IfTag.swift index 68c117d..2658bfc 100644 --- a/Sources/IfTag.swift +++ b/Sources/IfTag.swift @@ -18,6 +18,7 @@ let operators: [Operator] = [ .infix("and", 7, AndExpression.self), .prefix("not", 8, NotExpression.self), .infix("==", 10, EqualityExpression.self), + .infix("!=", 10, InequalityExpression.self), ] diff --git a/Tests/StencilTests/ExpressionSpec.swift b/Tests/StencilTests/ExpressionSpec.swift index d0e7bc3..feea653 100644 --- a/Tests/StencilTests/ExpressionSpec.swift +++ b/Tests/StencilTests/ExpressionSpec.swift @@ -162,7 +162,7 @@ func testExpressions() { } $0.it("evaluates to false with non equal lhs/rhs") { - print(expression) + try expect(expression.evaluate(context: Context(dictionary: ["lhs": "a", "rhs": "b"]))).to.beFalse() } $0.it("evaluates to true with nils") { @@ -190,6 +190,18 @@ func testExpressions() { } } + $0.describe("inequality expression") { + let expression = try! parseExpression(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() + } + + $0.it("evaluates to false with equal lhs/rhs") { + try expect(expression.evaluate(context: Context(dictionary: ["lhs": "b", "rhs": "b"]))).to.beFalse() + } + } + $0.describe("multiple expression") { let expression = try! parseExpression(components: ["one", "or", "two", "and", "not", "three"]) diff --git a/docs/builtins.rst b/docs/builtins.rst index 0053bf5..3d81499 100644 --- a/docs/builtins.rst +++ b/docs/builtins.rst @@ -106,6 +106,17 @@ Will be treated as: .. note:: The equality operator only supports numerical, string and boolean types. +``!=`` operator +""""""""""""""" + +.. code-block:: html+django + + {% if value != other_value %} + value is not equal to other_value + {% endif %} + +.. note:: The inequality operator only supports numerical, string and boolean types. + ``ifnot`` ~~~~~~~~~