diff --git a/lib/liquid/tags/if.rb b/lib/liquid/tags/if.rb index f060000..f0cd4db 100644 --- a/lib/liquid/tags/if.rb +++ b/lib/liquid/tags/if.rb @@ -15,16 +15,15 @@ module Liquid SyntaxHelp = "Syntax Error in tag 'if' - Valid syntax: if [expression]" Syntax = /(#{QuotedFragment})\s*([=!<>a-z_]+)?\s*(#{QuotedFragment})?/ ExpressionsAndOperators = /(?:\b(?:and|or)\b|(?:\s*(?!\b(?:and|or)\b)(?:#{QuotedFragment}|\S+)\s*)+)/ - - def initialize(tag_name, markup, tokens) - + + def initialize(tag_name, markup, tokens) @blocks = [] - + push_block('if', markup) - - super + + super end - + def unknown_tag(tag, markup, tokens) if ['elsif', 'else'].include?(tag) push_block(tag, markup) @@ -32,49 +31,49 @@ module Liquid super end end - + def render(context) context.stack do @blocks.each do |block| - if block.evaluate(context) - return render_all(block.attachment, context) + if block.evaluate(context) + return render_all(block.attachment, context) end - end + end '' end end - - private - - def push_block(tag, markup) - block = if tag == 'else' - ElseCondition.new - else - - expressions = markup.scan(ExpressionsAndOperators).reverse - raise(SyntaxError, SyntaxHelp) unless expressions.shift =~ Syntax - condition = Condition.new($1, $2, $3) - - while not expressions.empty? - operator = expressions.shift - - raise(SyntaxError, SyntaxHelp) unless expressions.shift.to_s =~ Syntax - - new_condition = Condition.new($1, $2, $3) - new_condition.send(operator.to_sym, condition) - condition = new_condition - end - - condition + private + + def push_block(tag, markup) + block = if tag == 'else' + ElseCondition.new + else + + expressions = markup.scan(ExpressionsAndOperators).reverse + raise(SyntaxError, SyntaxHelp) unless expressions.shift =~ Syntax + + condition = Condition.new($1, $2, $3) + + while not expressions.empty? + operator = expressions.shift + + raise(SyntaxError, SyntaxHelp) unless expressions.shift.to_s =~ Syntax + + new_condition = Condition.new($1, $2, $3) + new_condition.send(operator.to_sym, condition) + condition = new_condition + end + + condition + end + + @blocks.push(block) + @nodelist = block.attach(Array.new) end - - @blocks.push(block) - @nodelist = block.attach(Array.new) - end - - + + end Template.register_tag('if', If) -end \ No newline at end of file +end diff --git a/test/lib/liquid/condition_test.rb b/test/lib/liquid/condition_test.rb index 5027798..7dd096e 100644 --- a/test/lib/liquid/condition_test.rb +++ b/test/lib/liquid/condition_test.rb @@ -48,16 +48,14 @@ class ConditionTest < Test::Unit::TestCase @context = Liquid::Context.new @context['array'] = [1,2,3,4,5] - assert_evalutes_false "array", 'contains', '0' - assert_evalutes_true "array", 'contains', '1' - assert_evalutes_true "array", 'contains', '2' - assert_evalutes_true "array", 'contains', '3' - assert_evalutes_true "array", 'contains', '4' - assert_evalutes_true "array", 'contains', '5' - assert_evalutes_false "array", 'contains', '6' - - assert_evalutes_false "array", 'contains', '"1"' - + assert_evalutes_false "array", 'contains', '0' + assert_evalutes_true "array", 'contains', '1' + assert_evalutes_true "array", 'contains', '2' + assert_evalutes_true "array", 'contains', '3' + assert_evalutes_true "array", 'contains', '4' + assert_evalutes_true "array", 'contains', '5' + assert_evalutes_false "array", 'contains', '6' + assert_evalutes_false "array", 'contains', '"1"' end def test_contains_returns_false_for_nil_operands @@ -94,17 +92,23 @@ class ConditionTest < Test::Unit::TestCase assert_equal false, condition.evaluate end - def test_should_allow_custom_proc_operator Condition.operators['starts_with'] = Proc.new { |cond, left, right| left =~ %r{^#{right}} } - assert_evalutes_true "'bob'", 'starts_with', "'b'" - assert_evalutes_false "'bob'", 'starts_with', "'o'" + assert_evalutes_true "'bob'", 'starts_with', "'b'" + assert_evalutes_false "'bob'", 'starts_with', "'o'" ensure Condition.operators.delete 'starts_with' end + def test_left_or_right_may_contain_operators + @context = Liquid::Context.new + @context['one'] = @context['another'] = "gnomeslab-and-or-liquid" + + assert_evalutes_true "one", '==', "another" + end + private def assert_evalutes_true(left, op, right) assert Condition.new(left, op, right).evaluate(@context || Liquid::Context.new), diff --git a/test/lib/liquid/tags/if_else_test.rb b/test/lib/liquid/tags/if_else_test.rb index 2766290..5b4eb31 100644 --- a/test/lib/liquid/tags/if_else_test.rb +++ b/test/lib/liquid/tags/if_else_test.rb @@ -150,4 +150,10 @@ class IfElseTest < Test::Unit::TestCase ensure Condition.operators.delete 'contains' end + + # def test_operators_are_ignored_unless_isolated + # Condition.operators['contains'] = :[] + # + # assert_template_result('yes', %({% if 'gnomeslab' == 'gnomeslab' %}yes{% endif %})) + # end end # IfElseTest diff --git a/test/test_helper.rb b/test/test_helper.rb index a5100bb..74118ed 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -6,6 +6,7 @@ require 'test/unit' require 'test/unit/assertions' require 'caller' require 'breakpoint' +require 'ruby-debug' require File.join File.dirname(__FILE__), '..', 'lib', 'liquid'