From f1bc9f27df0435bbd21153261e3c7ea8bed2eedd Mon Sep 17 00:00:00 2001 From: Justin Li Date: Thu, 14 May 2015 14:10:45 -0400 Subject: [PATCH 1/4] Include message in assert_template_result --- test/test_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_helper.rb b/test/test_helper.rb index 8006c9d6..eb6d2f29 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -33,13 +33,13 @@ module Minitest include Liquid def assert_template_result(expected, template, assigns = {}, message = nil) - assert_equal expected, Template.parse(template).render!(assigns) + assert_equal expected, Template.parse(template).render!(assigns), message end def assert_template_result_matches(expected, template, assigns = {}, message = nil) return assert_template_result(expected, template, assigns, message) unless expected.is_a? Regexp - assert_match expected, Template.parse(template).render!(assigns) + assert_match expected, Template.parse(template).render!(assigns), message end def assert_match_syntax_error(match, template, registers = {}) From b4e5017c79c3125648745591f770ca509f07fa8a Mon Sep 17 00:00:00 2001 From: Justin Li Date: Thu, 14 May 2015 14:11:03 -0400 Subject: [PATCH 2/4] Add truth table test for multiple if conditions --- test/integration/tags/if_else_tag_test.rb | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/integration/tags/if_else_tag_test.rb b/test/integration/tags/if_else_tag_test.rb index 73a7accc..c23e3ed8 100644 --- a/test/integration/tags/if_else_tag_test.rb +++ b/test/integration/tags/if_else_tag_test.rb @@ -164,4 +164,25 @@ class IfElseTagTest < Minitest::Test assert_template_result('', %({% if 1 or throw or or 1 %}yes{% endif %})) end end + + def test_multiple_conditions + tpl = "{% if a or b and c %}true{% else %}false{% endif %}" + + tests = { + [true, true, true] => true, + [true, true, false] => true, + [true, false, true] => true, + [true, false, false] => true, + [false, true, true] => true, + [false, true, false] => false, + [false, false, true] => false, + [false, false, false] => false, + } + + tests.each do |vals, expected| + a, b, c = vals + assigns = { 'a' => a, 'b' => b, 'c' => c } + assert_template_result expected.to_s, tpl, assigns, assigns.to_s + end + end end From a9c7df931fdeb5ccf280dc772c6d057ebb38b9f7 Mon Sep 17 00:00:00 2001 From: Justin Li Date: Fri, 15 May 2015 13:37:53 -0400 Subject: [PATCH 3/4] Strict parse conditions in reverse order --- lib/liquid/tags/if.rb | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/liquid/tags/if.rb b/lib/liquid/tags/if.rb index 4901d4ad..d7f88aaf 100644 --- a/lib/liquid/tags/if.rb +++ b/lib/liquid/tags/if.rb @@ -84,14 +84,21 @@ module Liquid def strict_parse(markup) p = Parser.new(markup) - condition = parse_comparison(p) + conditions = [parse_comparison(p)] while op = (p.id?('and'.freeze) || p.id?('or'.freeze)) - new_cond = parse_comparison(p) + conditions << op << parse_comparison(p) + end + p.consume(:end_of_string) + + condition = conditions.pop + + until conditions.empty? + op = conditions.pop + new_cond = conditions.pop new_cond.send(op, condition) condition = new_cond end - p.consume(:end_of_string) condition end From a639a133803b2aec9ff5d32d4b70845253f86a67 Mon Sep 17 00:00:00 2001 From: Justin Li Date: Thu, 28 May 2015 16:16:30 -0400 Subject: [PATCH 4/4] Use cleaner recursive solution --- lib/liquid/tags/if.rb | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/lib/liquid/tags/if.rb b/lib/liquid/tags/if.rb index d7f88aaf..40176bba 100644 --- a/lib/liquid/tags/if.rb +++ b/lib/liquid/tags/if.rb @@ -83,23 +83,16 @@ module Liquid def strict_parse(markup) p = Parser.new(markup) - - conditions = [parse_comparison(p)] - - while op = (p.id?('and'.freeze) || p.id?('or'.freeze)) - conditions << op << parse_comparison(p) - end + condition = parse_binary_comparison(p) p.consume(:end_of_string) + condition + end - condition = conditions.pop - - until conditions.empty? - op = conditions.pop - new_cond = conditions.pop - new_cond.send(op, condition) - condition = new_cond + def parse_binary_comparison(p) + condition = parse_comparison(p) + if op = (p.id?('and'.freeze) || p.id?('or'.freeze)) + condition.send(op, parse_binary_comparison(p)) end - condition end