mirror of
https://github.com/Shopify/liquid.git
synced 2026-09-26 13:45:13 -07:00
Add rigid_parse to case/when
This commit is contained in:
committed by
Guilherme Carreiro
parent
e2a15334f0
commit
65a1c167b3
@@ -37,6 +37,10 @@ module Liquid
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def rigid_mode?
|
||||||
|
parse_context.error_mode == :rigid
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def rigid_parse_with_error_context(markup)
|
def rigid_parse_with_error_context(markup)
|
||||||
|
|||||||
+43
-6
@@ -31,12 +31,7 @@ module Liquid
|
|||||||
def initialize(tag_name, markup, options)
|
def initialize(tag_name, markup, options)
|
||||||
super
|
super
|
||||||
@blocks = []
|
@blocks = []
|
||||||
|
parse_with_selected_parser(markup)
|
||||||
if markup =~ Syntax
|
|
||||||
@left = parse_expression(Regexp.last_match(1))
|
|
||||||
else
|
|
||||||
raise SyntaxError, options[:locale].t("errors.syntax.case")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse(tokens)
|
def parse(tokens)
|
||||||
@@ -91,9 +86,51 @@ module Liquid
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def rigid_parse(markup)
|
||||||
|
parser = @parse_context.new_parser(markup)
|
||||||
|
@left = safe_parse_expression(parser)
|
||||||
|
parser.consume(:end_of_string)
|
||||||
|
end
|
||||||
|
|
||||||
|
def strict_parse(markup)
|
||||||
|
lax_parse(markup)
|
||||||
|
end
|
||||||
|
|
||||||
|
def lax_parse(markup)
|
||||||
|
if markup =~ Syntax
|
||||||
|
@left = parse_expression(Regexp.last_match(1))
|
||||||
|
else
|
||||||
|
raise SyntaxError, options[:locale].t("errors.syntax.case")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def record_when_condition(markup)
|
def record_when_condition(markup)
|
||||||
body = new_body
|
body = new_body
|
||||||
|
|
||||||
|
if rigid_mode?
|
||||||
|
parse_rigid_when(markup, body)
|
||||||
|
else
|
||||||
|
parse_lax_when(markup, body)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_rigid_when(markup, body)
|
||||||
|
parser = @parse_context.new_parser(markup)
|
||||||
|
|
||||||
|
loop do
|
||||||
|
expr = safe_parse_expression(parser)
|
||||||
|
block = Condition.new(@left, '==', expr)
|
||||||
|
block.attach(body)
|
||||||
|
@blocks << block
|
||||||
|
|
||||||
|
# Temporarily until support :or lexeme.
|
||||||
|
break unless parser.id?('or') || parser.consume?(:comma)
|
||||||
|
end
|
||||||
|
|
||||||
|
parser.consume(:end_of_string)
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_lax_when(markup, body)
|
||||||
while markup
|
while markup
|
||||||
unless markup =~ WhenSyntax
|
unless markup =~ WhenSyntax
|
||||||
raise SyntaxError, options[:locale].t("errors.syntax.case_invalid_when")
|
raise SyntaxError, options[:locale].t("errors.syntax.case_invalid_when")
|
||||||
|
|||||||
@@ -9,4 +9,124 @@ class CaseTagUnitTest < Minitest::Test
|
|||||||
template = Liquid::Template.parse('{% case var %}{% when true %}WHEN{% else %}ELSE{% endcase %}')
|
template = Liquid::Template.parse('{% case var %}{% when true %}WHEN{% else %}ELSE{% endcase %}')
|
||||||
assert_equal(['WHEN', 'ELSE'], template.root.nodelist[0].nodelist.map(&:nodelist).flatten)
|
assert_equal(['WHEN', 'ELSE'], template.root.nodelist[0].nodelist.map(&:nodelist).flatten)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_case_with_trailing_element
|
||||||
|
template = <<~LIQUID
|
||||||
|
{%- case 1 bar -%}
|
||||||
|
{%- when 1 -%}
|
||||||
|
one
|
||||||
|
{%- else -%}
|
||||||
|
two
|
||||||
|
{%- endcase -%}
|
||||||
|
LIQUID
|
||||||
|
|
||||||
|
[:lax, :strict].each do |mode|
|
||||||
|
with_error_mode(mode) { assert_template_result("one", template) }
|
||||||
|
end
|
||||||
|
|
||||||
|
with_error_mode(:rigid) do
|
||||||
|
error = assert_raises(Liquid::SyntaxError) { Template.parse(template) }
|
||||||
|
|
||||||
|
assert_match(/Expected end_of_string but found/, error.message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_case_when_trailing_element
|
||||||
|
template = <<~LIQUID
|
||||||
|
{%- case 1 -%}
|
||||||
|
{%- when 1 bar -%}
|
||||||
|
one
|
||||||
|
{%- else -%}
|
||||||
|
two
|
||||||
|
{%- endcase -%}
|
||||||
|
LIQUID
|
||||||
|
|
||||||
|
[:lax, :strict].each do |mode|
|
||||||
|
with_error_mode(mode) { assert_template_result("one", template) }
|
||||||
|
end
|
||||||
|
|
||||||
|
with_error_mode(:rigid) do
|
||||||
|
error = assert_raises(Liquid::SyntaxError) { Template.parse(template) }
|
||||||
|
|
||||||
|
assert_match(/Expected end_of_string but found/, error.message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_case_when_with_comma
|
||||||
|
template = <<~LIQUID
|
||||||
|
{%- case 1 -%}
|
||||||
|
{%- when 2, 1 -%}
|
||||||
|
one
|
||||||
|
{%- else -%}
|
||||||
|
two
|
||||||
|
{%- endcase -%}
|
||||||
|
LIQUID
|
||||||
|
|
||||||
|
[:lax, :strict, :rigid].each do |mode|
|
||||||
|
with_error_mode(mode) { assert_template_result("one", template) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_case_when_with_or
|
||||||
|
template = <<~LIQUID
|
||||||
|
{%- case 1 -%}
|
||||||
|
{%- when 2 or 1 -%}
|
||||||
|
one
|
||||||
|
{%- else -%}
|
||||||
|
two
|
||||||
|
{%- endcase -%}
|
||||||
|
LIQUID
|
||||||
|
|
||||||
|
[:lax, :strict, :rigid].each do |mode|
|
||||||
|
with_error_mode(mode) { assert_template_result("one", template) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_case_with_invalid_expression
|
||||||
|
template = <<~LIQUID
|
||||||
|
{%- case foo=>bar -%}
|
||||||
|
{%- when 'baz' -%}
|
||||||
|
one
|
||||||
|
{%- else -%}
|
||||||
|
two
|
||||||
|
{%- endcase -%}
|
||||||
|
LIQUID
|
||||||
|
assigns = { 'foo' => { 'bar' => 'baz' } }
|
||||||
|
|
||||||
|
[:lax, :strict].each do |mode|
|
||||||
|
with_error_mode(mode) do
|
||||||
|
assert_template_result("one", template, assigns)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
with_error_mode(:rigid) do
|
||||||
|
error = assert_raises(Liquid::SyntaxError) { Template.parse(template) }
|
||||||
|
|
||||||
|
assert_match(/Unexpected character =/, error.message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_case_when_with_invalid_expression
|
||||||
|
template = <<~LIQUID
|
||||||
|
{%- case 'baz' -%}
|
||||||
|
{%- when foo=>bar -%}
|
||||||
|
one
|
||||||
|
{%- else -%}
|
||||||
|
two
|
||||||
|
{%- endcase -%}
|
||||||
|
LIQUID
|
||||||
|
assigns = { 'foo' => { 'bar' => 'baz' } }
|
||||||
|
|
||||||
|
[:lax, :strict].each do |mode|
|
||||||
|
with_error_mode(mode) do
|
||||||
|
assert_template_result("one", template, assigns)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
with_error_mode(:rigid) do
|
||||||
|
error = assert_raises(Liquid::SyntaxError) { Template.parse(template) }
|
||||||
|
|
||||||
|
assert_match(/Unexpected character =/, error.message)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user