mirror of
https://github.com/Shopify/liquid.git
synced 2026-09-16 17:30:43 -07:00
A better fix for "and"/"or" in strings
(now with less side effects)
This commit is contained in:
@@ -21,10 +21,6 @@ module Liquid
|
|||||||
def self.operators
|
def self.operators
|
||||||
@@operators
|
@@operators
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.operator_regexp
|
|
||||||
Regexp.new(@@operators.keys.sort_by(&:length).reverse.map {|k| Regexp.escape(k)}.join('|'))
|
|
||||||
end
|
|
||||||
|
|
||||||
attr_reader :attachment
|
attr_reader :attachment
|
||||||
attr_accessor :left, :operator, :right
|
attr_accessor :left, :operator, :right
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ module Liquid
|
|||||||
#
|
#
|
||||||
class If < Block
|
class If < Block
|
||||||
SyntaxHelp = "Syntax Error in tag 'if' - Valid syntax: if [expression]"
|
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})?/
|
ExpressionsAndOperators = /(?:and|or|(?:\s*(?!\b(?:and|or)\b)(?:#{QuotedFragment}|\S+)\s*)+)/
|
||||||
|
|
||||||
def initialize(tag_name, markup, tokens)
|
def initialize(tag_name, markup, tokens)
|
||||||
|
|
||||||
@@ -51,9 +51,7 @@ module Liquid
|
|||||||
ElseCondition.new
|
ElseCondition.new
|
||||||
else
|
else
|
||||||
|
|
||||||
# expressions = markup.split(/\b(and|or)\b/).reverse
|
expressions = markup.scan(ExpressionsAndOperators).reverse
|
||||||
|
|
||||||
expressions = markup.scan(ExpressionsAndOperators).flatten.compact.reverse
|
|
||||||
raise(SyntaxError, SyntaxHelp) unless expressions.shift =~ Syntax
|
raise(SyntaxError, SyntaxHelp) unless expressions.shift =~ Syntax
|
||||||
|
|
||||||
condition = Condition.new($1, $2, $3)
|
condition = Condition.new($1, $2, $3)
|
||||||
|
|||||||
@@ -38,4 +38,17 @@ class ParsingQuirksTest < Test::Unit::TestCase
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_meaningless_parens
|
||||||
|
assigns = {'b' => 'bar', 'c' => 'baz'}
|
||||||
|
markup = "a == 'foo' or (b == 'bar' and c == 'baz') or false"
|
||||||
|
assert_template_result(' YES ',"{% if #{markup} %} YES {% endif %}", assigns)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_unexpected_characters_silently_eat_logic
|
||||||
|
markup = "true && false"
|
||||||
|
assert_template_result(' YES ',"{% if #{markup} %} YES {% endif %}")
|
||||||
|
markup = "false || true"
|
||||||
|
assert_template_result('',"{% if #{markup} %} YES {% endif %}")
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -17,31 +17,31 @@ class StatementsTest < Test::Unit::TestCase
|
|||||||
assert_equal expected, Template.parse(text).render
|
assert_equal expected, Template.parse(text).render
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_zero_gt_zero
|
def test_true_lq_true
|
||||||
text = %| {% if 0 > 0 %} true {% else %} false {% endif %} |
|
text = %| {% if 0 > 0 %} true {% else %} false {% endif %} |
|
||||||
expected = %| false |
|
expected = %| false |
|
||||||
assert_equal expected, Template.parse(text).render
|
assert_equal expected, Template.parse(text).render
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_one_gt_zero
|
def test_one_lq_zero
|
||||||
text = %| {% if 1 > 0 %} true {% else %} false {% endif %} |
|
text = %| {% if 1 > 0 %} true {% else %} false {% endif %} |
|
||||||
expected = %| true |
|
expected = %| true |
|
||||||
assert_equal expected, Template.parse(text).render
|
assert_equal expected, Template.parse(text).render
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_zero_lt_one
|
def test_zero_lq_one
|
||||||
text = %| {% if 0 < 1 %} true {% else %} false {% endif %} |
|
text = %| {% if 0 < 1 %} true {% else %} false {% endif %} |
|
||||||
expected = %| true |
|
expected = %| true |
|
||||||
assert_equal expected, Template.parse(text).render
|
assert_equal expected, Template.parse(text).render
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_zero_lt_or_equal_zero
|
def test_zero_lq_or_equal_one
|
||||||
text = %| {% if 0 <= 0 %} true {% else %} false {% endif %} |
|
text = %| {% if 0 <= 0 %} true {% else %} false {% endif %} |
|
||||||
expected = %| true |
|
expected = %| true |
|
||||||
assert_equal expected, Template.parse(text).render
|
assert_equal expected, Template.parse(text).render
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_zero_lt_or_equal_zero_involving_nil
|
def test_zero_lq_or_equal_one_involving_nil
|
||||||
text = %| {% if null <= 0 %} true {% else %} false {% endif %} |
|
text = %| {% if null <= 0 %} true {% else %} false {% endif %} |
|
||||||
expected = %| false |
|
expected = %| false |
|
||||||
assert_equal expected, Template.parse(text).render
|
assert_equal expected, Template.parse(text).render
|
||||||
@@ -52,7 +52,7 @@ class StatementsTest < Test::Unit::TestCase
|
|||||||
assert_equal expected, Template.parse(text).render
|
assert_equal expected, Template.parse(text).render
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_zero_gt_or_equal_zero
|
def test_zero_lqq_or_equal_one
|
||||||
text = %| {% if 0 >= 0 %} true {% else %} false {% endif %} |
|
text = %| {% if 0 >= 0 %} true {% else %} false {% endif %} |
|
||||||
expected = %| true |
|
expected = %| true |
|
||||||
assert_equal expected, Template.parse(text).render
|
assert_equal expected, Template.parse(text).render
|
||||||
|
|||||||
Reference in New Issue
Block a user