mirror of
https://github.com/Shopify/liquid.git
synced 2026-09-29 15:15:19 -07:00
Update the implementation to make {% doc %} as strict as {% raw %}
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
errors:
|
errors:
|
||||||
syntax:
|
syntax:
|
||||||
tag_unexpected_args: "Syntax Error in '%{tag}' - Valid syntax: %{tag}"
|
tag_unexpected_args: "Syntax Error in '%{tag}' - Valid syntax: %{tag}"
|
||||||
|
block_tag_unexpected_args: "Syntax Error in '%{tag}' - Valid syntax: {% %{tag} %}{% end%{tag} %}"
|
||||||
assign: "Syntax Error in 'assign' - Valid syntax: assign [var] = [source]"
|
assign: "Syntax Error in 'assign' - Valid syntax: assign [var] = [source]"
|
||||||
capture: "Syntax Error in 'capture' - Valid syntax: capture [var]"
|
capture: "Syntax Error in 'capture' - Valid syntax: capture [var]"
|
||||||
case: "Syntax Error in 'case' - Valid syntax: case [condition]"
|
case: "Syntax Error in 'case' - Valid syntax: case [condition]"
|
||||||
|
|||||||
+26
-27
@@ -25,45 +25,44 @@ module Liquid
|
|||||||
# {% enddoc %}
|
# {% enddoc %}
|
||||||
# {{ foo }}, {{ bar }}!
|
# {{ foo }}, {{ bar }}!
|
||||||
class Doc < Block
|
class Doc < Block
|
||||||
def render_to_output_buffer(_context, output)
|
TAG_UNEXPECTED_ARGS = /\A\s*\z/
|
||||||
output
|
|
||||||
|
def initialize(tag_name, markup, parse_context)
|
||||||
|
super
|
||||||
|
ensure_valid_markup(tag_name, markup, parse_context)
|
||||||
end
|
end
|
||||||
|
|
||||||
def unknown_tag(_tag, _markup, _tokens)
|
def parse(tokens)
|
||||||
end
|
while (token = tokens.shift)
|
||||||
|
tag_name = token =~ BlockBody::FullTokenPossiblyInvalid && Regexp.last_match(2)
|
||||||
|
|
||||||
def blank?
|
raise_nested_doc_error if tag_name == @tag_name
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
def parse_body(body, tokenizer)
|
if tag_name == block_delimiter
|
||||||
while (token = tokenizer.send(:shift))
|
parse_context.trim_whitespace = (token[-3] == WhitespaceControl)
|
||||||
tag_name = if tokenizer.for_liquid_tag
|
return
|
||||||
next if token.empty? || token.match?(BlockBody::WhitespaceOrNothing)
|
|
||||||
|
|
||||||
tag_name_match = BlockBody::LiquidTagToken.match(token)
|
|
||||||
|
|
||||||
next if tag_name_match.nil?
|
|
||||||
|
|
||||||
tag_name_match[1]
|
|
||||||
else
|
|
||||||
token =~ BlockBody::FullToken
|
|
||||||
Regexp.last_match(2)
|
|
||||||
end
|
|
||||||
|
|
||||||
raise_nested_doc_error if tag_name == "doc"
|
|
||||||
|
|
||||||
if tag_name == "enddoc"
|
|
||||||
parse_context.trim_whitespace = (token[-3] == WhitespaceControl) unless tokenizer.for_liquid_tag
|
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
raise_tag_never_closed(block_name)
|
raise_tag_never_closed(block_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def render_to_output_buffer(_context, output)
|
||||||
|
output
|
||||||
|
end
|
||||||
|
|
||||||
|
def blank?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def ensure_valid_markup(tag_name, markup, parse_context)
|
||||||
|
unless TAG_UNEXPECTED_ARGS.match?(markup)
|
||||||
|
raise SyntaxError, parse_context.locale.t("errors.syntax.block_tag_unexpected_args", tag: tag_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def raise_nested_doc_error
|
def raise_nested_doc_error
|
||||||
raise SyntaxError, parse_context.locale.t("errors.syntax.doc_invalid_nested")
|
raise SyntaxError, parse_context.locale.t("errors.syntax.doc_invalid_nested")
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -20,32 +20,26 @@ class DocTagUnitTest < Minitest::Test
|
|||||||
assert_template_result('', template)
|
assert_template_result('', template)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_doc_tag_inside_liquid_tag
|
def test_doc_tag_does_not_support_extra_arguments
|
||||||
template = <<~LIQUID.chomp
|
error = assert_raises(Liquid::SyntaxError) do
|
||||||
{% liquid
|
template = <<~LIQUID.chomp
|
||||||
doc
|
{% doc extra %}
|
||||||
Assigns foo to 1.
|
{% enddoc %}
|
||||||
enddoc
|
LIQUID
|
||||||
assign foo = 1
|
|
||||||
%}
|
|
||||||
LIQUID
|
|
||||||
|
|
||||||
assert_template_result('', template)
|
Liquid::Template.parse(template)
|
||||||
|
end
|
||||||
|
|
||||||
|
exp_error = "Liquid syntax error: Syntax Error in 'doc' - Valid syntax: {% doc %}{% enddoc %}"
|
||||||
|
act_error = error.message
|
||||||
|
|
||||||
|
assert_equal(exp_error, act_error)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_doc_tag_inside_liquid_tag_with_control_flow_nodes
|
def test_doc_tag_must_support_valid_tags
|
||||||
template = <<~LIQUID.chomp
|
assert_match_syntax_error("Liquid syntax error (line 1): 'doc' tag was never closed", '{% doc %} foo')
|
||||||
{% liquid
|
assert_match_syntax_error("Liquid syntax error (line 1): Syntax Error in 'doc' - Valid syntax: {% doc %}{% enddoc %}", '{% doc } foo {% enddoc %}')
|
||||||
if 1 != 1
|
assert_match_syntax_error("Liquid syntax error (line 1): Syntax Error in 'doc' - Valid syntax: {% doc %}{% enddoc %}", '{% doc } foo %}{% enddoc %}')
|
||||||
doc
|
|
||||||
else
|
|
||||||
echo 123
|
|
||||||
enddoc
|
|
||||||
endif
|
|
||||||
%}
|
|
||||||
LIQUID
|
|
||||||
|
|
||||||
assert_template_result('', template)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_doc_tag_ignores_liquid_nodes
|
def test_doc_tag_ignores_liquid_nodes
|
||||||
@@ -103,37 +97,23 @@ class DocTagUnitTest < Minitest::Test
|
|||||||
assert_template_result('', template)
|
assert_template_result('', template)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_doc_tag_raises_an_error_for_unclosed_assign
|
def test_doc_tag_ignores_unclosed_assign
|
||||||
error = assert_raises(Liquid::SyntaxError) do
|
template = <<~LIQUID.chomp
|
||||||
template = <<~LIQUID.chomp
|
{% doc %}
|
||||||
{% doc %}
|
{% assign foo = "1"
|
||||||
{% assign foo = "1"
|
{% enddoc %}
|
||||||
{% enddoc %}
|
LIQUID
|
||||||
LIQUID
|
|
||||||
|
|
||||||
Liquid::Template.parse(template)
|
assert_template_result('', template)
|
||||||
end
|
|
||||||
|
|
||||||
exp_error = "Liquid syntax error: 'doc' tag was never closed"
|
|
||||||
act_error = error.message
|
|
||||||
|
|
||||||
assert_equal(exp_error, act_error)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_doc_tag_raises_an_error_for_malformed_syntax
|
def test_doc_tag_ignores_malformed_syntax
|
||||||
error = assert_raises(Liquid::SyntaxError) do
|
template = <<~LIQUID.chomp
|
||||||
template = <<~LIQUID.chomp
|
{% doc %}
|
||||||
{% doc %}
|
{% {{ {%- enddoc %}
|
||||||
{% {{ {%- enddoc %}
|
LIQUID
|
||||||
LIQUID
|
|
||||||
|
|
||||||
Liquid::Template.parse(template)
|
assert_template_result('', template)
|
||||||
end
|
|
||||||
|
|
||||||
exp_error = "Liquid syntax error: 'doc' tag was never closed"
|
|
||||||
act_error = error.message
|
|
||||||
|
|
||||||
assert_equal(exp_error, act_error)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_doc_tag_preserves_error_line_numbers
|
def test_doc_tag_preserves_error_line_numbers
|
||||||
@@ -157,19 +137,6 @@ class DocTagUnitTest < Minitest::Test
|
|||||||
assert_template_result("Hello!", " {%- doc -%}123{%- enddoc -%}Hello!")
|
assert_template_result("Hello!", " {%- doc -%}123{%- enddoc -%}Hello!")
|
||||||
assert_template_result("Hello!", "{%- doc -%}123{%- enddoc -%} Hello!")
|
assert_template_result("Hello!", "{%- doc -%}123{%- enddoc -%} Hello!")
|
||||||
assert_template_result("Hello!", " {%- doc -%}123{%- enddoc -%} Hello!")
|
assert_template_result("Hello!", " {%- doc -%}123{%- enddoc -%} Hello!")
|
||||||
|
|
||||||
# Whitespace control within liquid tags
|
|
||||||
assert_template_result("Hello!World!", <<~LIQUID.chomp)
|
|
||||||
Hello!
|
|
||||||
{%- liquid
|
|
||||||
doc
|
|
||||||
this is inside a liquid tag
|
|
||||||
enddoc
|
|
||||||
-%}
|
|
||||||
World!
|
|
||||||
LIQUID
|
|
||||||
|
|
||||||
# Multiline whitespace control
|
|
||||||
assert_template_result("Hello!", <<~LIQUID.chomp)
|
assert_template_result("Hello!", <<~LIQUID.chomp)
|
||||||
{%- doc %}Whitespace control!{% enddoc -%}
|
{%- doc %}Whitespace control!{% enddoc -%}
|
||||||
Hello!
|
Hello!
|
||||||
@@ -189,6 +156,5 @@ class DocTagUnitTest < Minitest::Test
|
|||||||
assert_template_result('', "{% doc %}123{% enddoc\txyz %}")
|
assert_template_result('', "{% doc %}123{% enddoc\txyz %}")
|
||||||
assert_template_result('', "{% doc %}123{% enddoc\nxyz %}")
|
assert_template_result('', "{% doc %}123{% enddoc\nxyz %}")
|
||||||
assert_template_result('', "{% doc %}123{% enddoc\n xyz enddoc %}")
|
assert_template_result('', "{% doc %}123{% enddoc\n xyz enddoc %}")
|
||||||
assert_template_result('', "{%doc}{% assign a = 1 %}{%enddoc}{% endif %}")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user