From f42ce88456904930a9635a551213129cef7b1982 Mon Sep 17 00:00:00 2001 From: James MacAulay Date: Mon, 14 Sep 2009 15:01:26 -0400 Subject: [PATCH] fixed conditions with strings containing "and"/"or" --- lib/liquid/condition.rb | 4 ++++ lib/liquid/tags/if.rb | 7 +++++-- test/if_else_test.rb | 8 ++++++++ test/statements_test.rb | 12 ++++++------ 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/lib/liquid/condition.rb b/lib/liquid/condition.rb index ade7ac1f..06d20347 100644 --- a/lib/liquid/condition.rb +++ b/lib/liquid/condition.rb @@ -21,6 +21,10 @@ module Liquid def self.operators @@operators end + + def self.operator_regexp + Regexp.new(@@operators.keys.sort_by(&:length).reverse.map {|k| Regexp.escape(k)}.join('|')) + end attr_reader :attachment attr_accessor :left, :operator, :right diff --git a/lib/liquid/tags/if.rb b/lib/liquid/tags/if.rb index 8ff47088..304d8f1e 100644 --- a/lib/liquid/tags/if.rb +++ b/lib/liquid/tags/if.rb @@ -13,7 +13,8 @@ module Liquid # class If < Block SyntaxHelp = "Syntax Error in tag 'if' - Valid syntax: if [expression]" - Syntax = /(#{QuotedFragment})\s*([=!<>a-z_]+)?\s*(#{QuotedFragment})?/ + Syntax = /(#{QuotedFragment})\s*(?:([=!<>a-z_]+)\s*(#{QuotedFragment}))?/ + ExpressionsAndOperators = /and|or|#{QuotedFragment}\s*(?:(?!and|or)(?:[=!<>a-z_]+)\s*#{QuotedFragment})?/ def initialize(tag_name, markup, tokens) @@ -50,7 +51,9 @@ module Liquid ElseCondition.new else - expressions = markup.split(/\b(and|or)\b/).reverse + # expressions = markup.split(/\b(and|or)\b/).reverse + + expressions = markup.scan(ExpressionsAndOperators).flatten.compact.reverse raise(SyntaxError, SyntaxHelp) unless expressions.shift =~ Syntax condition = Condition.new($1, $2, $3) diff --git a/test/if_else_test.rb b/test/if_else_test.rb index 5daef3f1..629dd12b 100644 --- a/test/if_else_test.rb +++ b/test/if_else_test.rb @@ -36,6 +36,14 @@ class IfElseTest < Test::Unit::TestCase assert_template_result('','{% if a == false or b == false %} YES {% endif %}', 'a' => true, 'b' => true) end + def test_comparison_of_strings_containing_and_or_or + assert_nothing_raised do + awful_markup = "a == 'and' and b == 'or' and c == 'foo and bar' and d == 'bar or baz' and e == 'foo' and foo and bar" + assigns = {'a' => 'and', 'b' => 'or', 'c' => 'foo and bar', 'd' => 'bar or baz', 'e' => 'foo', 'foo' => true, 'bar' => true} + assert_template_result(' YES ',"{% if #{awful_markup} %} YES {% endif %}", assigns) + end + end + def test_if_and assert_template_result(' YES ','{% if true and true %} YES {% endif %}') assert_template_result('','{% if false and true %} YES {% endif %}') diff --git a/test/statements_test.rb b/test/statements_test.rb index 63a41040..25e272a9 100644 --- a/test/statements_test.rb +++ b/test/statements_test.rb @@ -17,31 +17,31 @@ class StatementsTest < Test::Unit::TestCase assert_equal expected, Template.parse(text).render end - def test_true_lq_true + def test_zero_gt_zero text = %| {% if 0 > 0 %} true {% else %} false {% endif %} | expected = %| false | assert_equal expected, Template.parse(text).render end - def test_one_lq_zero + def test_one_gt_zero text = %| {% if 1 > 0 %} true {% else %} false {% endif %} | expected = %| true | assert_equal expected, Template.parse(text).render end - def test_zero_lq_one + def test_zero_lt_one text = %| {% if 0 < 1 %} true {% else %} false {% endif %} | expected = %| true | assert_equal expected, Template.parse(text).render end - def test_zero_lq_or_equal_one + def test_zero_lt_or_equal_zero text = %| {% if 0 <= 0 %} true {% else %} false {% endif %} | expected = %| true | assert_equal expected, Template.parse(text).render end - def test_zero_lq_or_equal_one_involving_nil + def test_zero_lt_or_equal_zero_involving_nil text = %| {% if null <= 0 %} true {% else %} false {% endif %} | expected = %| false | assert_equal expected, Template.parse(text).render @@ -52,7 +52,7 @@ class StatementsTest < Test::Unit::TestCase assert_equal expected, Template.parse(text).render end - def test_zero_lqq_or_equal_one + def test_zero_gt_or_equal_zero text = %| {% if 0 >= 0 %} true {% else %} false {% endif %} | expected = %| true | assert_equal expected, Template.parse(text).render