mirror of
https://github.com/Shopify/liquid.git
synced 2026-09-16 17:30:43 -07:00
Use BinaryExpression instead of Condition for comparisons
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'test_helper'
|
||||
|
||||
class BinaryExpressionTest < Minitest::Test
|
||||
include Liquid
|
||||
|
||||
def test_simple_comparison_evaluation
|
||||
assert_eval(false, BinaryExpression.new(5, ">", 5))
|
||||
assert_eval(true, BinaryExpression.new(5, ">=", 5))
|
||||
assert_eval(false, BinaryExpression.new(5, "<", 5))
|
||||
assert_eval(true, BinaryExpression.new(5, "<=", 5))
|
||||
assert_eval(true, BinaryExpression.new("abcd", "contains", "a"))
|
||||
end
|
||||
|
||||
def test_complex_evaluation
|
||||
# 1 > 2 == 2 > 3
|
||||
assert_eval(true, BinaryExpression.new(
|
||||
BinaryExpression.new(1, '>', 2),
|
||||
'==',
|
||||
BinaryExpression.new(2, '>', 3),
|
||||
))
|
||||
|
||||
# 1 > 2 != 2 > 3
|
||||
assert_eval(false, BinaryExpression.new(
|
||||
BinaryExpression.new(1, '>', 2),
|
||||
'!=',
|
||||
BinaryExpression.new(2, '>', 3),
|
||||
))
|
||||
|
||||
# a > 0 == b.prop > 0
|
||||
assert_eval(
|
||||
true,
|
||||
BinaryExpression.new(
|
||||
BinaryExpression.new(var('a'), '>', 0),
|
||||
'==',
|
||||
BinaryExpression.new(var('b.prop'), '>', 0),
|
||||
),
|
||||
{ 'a' => 1, 'b' => { 'prop' => 2 } },
|
||||
)
|
||||
end
|
||||
|
||||
def test_method_literal_equality
|
||||
empty = MethodLiteral.new(:empty?, '')
|
||||
|
||||
# a == empty, empty == a
|
||||
assert_eval(false, BinaryExpression.new("123", "==", empty))
|
||||
assert_eval(true, BinaryExpression.new("", "==", empty))
|
||||
assert_eval(false, BinaryExpression.new(empty, "==", "123"))
|
||||
assert_eval(true, BinaryExpression.new(empty, "==", ""))
|
||||
|
||||
# a does not have .empty?
|
||||
assert_eval(nil, BinaryExpression.new(1, "==", empty))
|
||||
assert_eval(nil, BinaryExpression.new(true, "==", empty))
|
||||
assert_eval(nil, BinaryExpression.new(false, "==", empty))
|
||||
assert_eval(nil, BinaryExpression.new(nil, "==", empty))
|
||||
|
||||
# a != empty
|
||||
assert_eval(true, BinaryExpression.new("123", "!=", empty))
|
||||
assert_eval(false, BinaryExpression.new("", "!=", empty))
|
||||
assert_eval(true, BinaryExpression.new(empty, "!=", "123"))
|
||||
assert_eval(false, BinaryExpression.new(empty, "!=", ""))
|
||||
|
||||
# a does not have .empty?
|
||||
assert_eval(true, BinaryExpression.new(1, "!=", empty))
|
||||
assert_eval(true, BinaryExpression.new(true, "!=", empty))
|
||||
assert_eval(true, BinaryExpression.new(false, "!=", empty))
|
||||
assert_eval(true, BinaryExpression.new(nil, "!=", empty))
|
||||
end
|
||||
|
||||
def test_method_literal_comparison
|
||||
empty = MethodLiteral.new(:empty?, '')
|
||||
|
||||
['>', '>='].each do |op|
|
||||
assert_eval(nil, BinaryExpression.new("123", op, empty))
|
||||
assert_eval(nil, BinaryExpression.new("", op, empty))
|
||||
assert_eval(nil, BinaryExpression.new(empty, op, "123"))
|
||||
assert_eval(nil, BinaryExpression.new(empty, op, ""))
|
||||
end
|
||||
|
||||
# Interesting case, contains on strings does include?(right.to_s)
|
||||
assert_eval(true, BinaryExpression.new("123", "contains", empty))
|
||||
assert_eval(true, BinaryExpression.new("", "contains", empty))
|
||||
end
|
||||
|
||||
def assert_eval(expected, expr, assigns = {})
|
||||
actual = expr.evaluate(context(assigns))
|
||||
message = "Expected '#{expr}' to evaluate to '#{expected}'"
|
||||
return assert_nil(actual, message) if expected.nil?
|
||||
|
||||
assert_equal(expected, actual, message)
|
||||
end
|
||||
|
||||
def var(markup)
|
||||
Parser.new(markup).variable_lookup
|
||||
end
|
||||
|
||||
def context(assigns = {})
|
||||
Context.build(outer_scope: assigns)
|
||||
end
|
||||
end
|
||||
@@ -183,7 +183,7 @@ class ConditionUnitTest < Minitest::Test
|
||||
parser = parse_context.new_parser('blank')
|
||||
result = Condition.parse_expression(parser)
|
||||
|
||||
assert_instance_of(Condition::MethodLiteral, result)
|
||||
assert_instance_of(MethodLiteral, result)
|
||||
end
|
||||
|
||||
# Tests for blank? comparison without ActiveSupport
|
||||
|
||||
@@ -82,24 +82,24 @@ class ParserUnitTest < Minitest::Test
|
||||
expr = p.expression
|
||||
assert(expr.is_a?(BinaryExpression))
|
||||
assert_equal('==', expr.operator)
|
||||
assert_equal('a', expr.left.name)
|
||||
assert_equal('b', expr.right.name)
|
||||
assert_equal('a', expr.left_node.name)
|
||||
assert_equal('b', expr.right_node.name)
|
||||
|
||||
# BinaryExpression(==)
|
||||
# left: BinaryExpression(<)
|
||||
# left: 0
|
||||
# right: 5
|
||||
# right: BinaryExpression(>)
|
||||
# left: 6
|
||||
# right: 1
|
||||
# left_node: BinaryExpression(<)
|
||||
# left_node: 0
|
||||
# right_node: 5
|
||||
# right_node: BinaryExpression(>)
|
||||
# left_node: 6
|
||||
# right_node: 1
|
||||
p = new_parser("0 < 5 == 6 > 1")
|
||||
expr = p.expression
|
||||
assert(expr.is_a?(BinaryExpression))
|
||||
assert_equal('==', expr.operator)
|
||||
assert_equal(0, expr.left.left)
|
||||
assert_equal(5, expr.left.right)
|
||||
assert_equal(6, expr.right.left)
|
||||
assert_equal(1, expr.right.right)
|
||||
assert_equal(0, expr.left_node.left_node)
|
||||
assert_equal(5, expr.left_node.right_node)
|
||||
assert_equal(6, expr.right_node.left_node)
|
||||
assert_equal(1, expr.right_node.right_node)
|
||||
end
|
||||
|
||||
def test_comparison
|
||||
@@ -107,23 +107,23 @@ class ParserUnitTest < Minitest::Test
|
||||
expr = p.expression
|
||||
assert(expr.is_a?(BinaryExpression))
|
||||
assert_equal('>', expr.operator)
|
||||
assert(expr.left.is_a?(VariableLookup))
|
||||
assert_equal('a', expr.left.name)
|
||||
assert(expr.right.is_a?(VariableLookup))
|
||||
assert_equal('b', expr.right.name)
|
||||
assert(expr.left_node.is_a?(VariableLookup))
|
||||
assert_equal('a', expr.left_node.name)
|
||||
assert(expr.right_node.is_a?(VariableLookup))
|
||||
assert_equal('b', expr.right_node.name)
|
||||
|
||||
# BinaryExpression(>=)
|
||||
# left: BinaryExpression(>)
|
||||
# left: 10
|
||||
# right: 5
|
||||
# right: 4
|
||||
# left_node: BinaryExpression(>)
|
||||
# left_node: 10
|
||||
# right_node: 5
|
||||
# right_node: 4
|
||||
p = new_parser("10 > 5 >= 4")
|
||||
expr = p.expression
|
||||
assert(expr.is_a?(BinaryExpression))
|
||||
assert_equal('>=', expr.operator)
|
||||
assert_equal(10, expr.left.left)
|
||||
assert_equal(5, expr.left.right)
|
||||
assert_equal(4, expr.right)
|
||||
assert_equal(10, expr.left_node.left_node)
|
||||
assert_equal(5, expr.left_node.right_node)
|
||||
assert_equal(4, expr.right_node)
|
||||
end
|
||||
|
||||
def test_number
|
||||
|
||||
Reference in New Issue
Block a user