Add error mode switching

This commit is contained in:
Tristan Hume
2013-07-26 11:45:13 -04:00
parent 8b1dff9d98
commit 87b8ee7341
7 changed files with 58 additions and 6 deletions
+4
View File
@@ -30,6 +30,10 @@ namespace :benchmark do
ruby "./performance/benchmark.rb"
end
desc "Run the liquid benchmark with lax parsing"
task :lax do
ruby "./performance/benchmark.rb lax"
end
end
+18 -2
View File
@@ -29,6 +29,7 @@ module Liquid
end
def render(context)
context.errors += @warnings if @warnings
context.stack do
@blocks.each do |block|
if block.evaluate(context)
@@ -52,7 +53,22 @@ module Liquid
@nodelist = block.attach(Array.new)
end
def old_parse(markup)
def parse_condition(markup)
case Template.error_mode
when :strict then strict_parse(markup)
when :lax then lax_parse(markup)
when :warn
begin
return strict_parse(markup)
rescue SyntaxError => e
@warnings ||= []
@warnings << e
return lax_parse(markup)
end
end
end
def lax_parse(markup)
expressions = markup.scan(ExpressionsAndOperators).reverse
raise(SyntaxError, SyntaxHelp) unless expressions.shift =~ Syntax
@@ -71,7 +87,7 @@ module Liquid
condition
end
def parse_condition(markup)
def strict_parse(markup)
p = Parser.new(markup)
condition = parse_comparison(p)
+12
View File
@@ -34,6 +34,18 @@ module Liquid
@tags ||= {}
end
# Sets how strict the parser should be.
# :lax acts like liquid 2.5 and silently ignores malformed tags in most cases.
# :warn is the default and will give deprecation warnings when invalid syntax is used.
# :strict will enforce correct syntax.
def error_mode=(mode)
@error_mode = mode
end
def error_mode
@error_mode || :warn
end
# Pass a module with filter methods which should be available
# to all liquid views. Good for registering the standard library
def register_filter(mod)
+19 -4
View File
@@ -17,11 +17,24 @@ module Liquid
def initialize(markup)
@markup = markup
@name = nil
@filters = []
parse(markup)
@warning = nil
case Template.error_mode
when :strict then strict_parse(markup)
when :lax then lax_parse(markup)
when :warn
begin
strict_parse(markup)
rescue SyntaxError => e
@warning = e
lax_parse(markup)
end
end
end
def old_parse(markup)
def lax_parse(markup)
@filters = []
if match = markup.match(/\s*(#{QuotedFragment})(.*)/o)
@name = match[1]
if match[2].match(/#{FilterSeparator}\s*(.*)/o)
@@ -37,7 +50,8 @@ module Liquid
end
end
def parse(markup)
def strict_parse(markup)
@filters = []
p = Parser.new(markup)
# Could be just filters with no input
@name = p.look(:pipe) ? '' : p.expression
@@ -61,6 +75,7 @@ module Liquid
def render(context)
return '' if @name.nil?
context.errors << @warning if @warning
@filters.inject(context[@name]) do |output, filter|
filterargs = []
keyword_args = {}
+1
View File
@@ -2,6 +2,7 @@ require 'rubygems'
require 'benchmark'
require File.dirname(__FILE__) + '/theme_runner'
Liquid::Template.error_mode = ARGV.first.to_sym if ARGV.first
profiler = ThemeRunner.new
Benchmark.bmbm do |x|
+1
View File
@@ -63,6 +63,7 @@ class ErrorHandlingTest < Test::Unit::TestCase
end
def test_unrecognized_operator
Template.error_mode = :strict
assert_raise(SyntaxError) do
Liquid::Template.parse(' {% if 1 =! 2 %}ok{% endif %} ')
end
+3
View File
@@ -30,6 +30,7 @@ class ParsingQuirksTest < Test::Unit::TestCase
end
def test_error_on_empty_filter
Template.error_mode = :strict
assert_nothing_raised do
Template.parse("{{test}}")
Template.parse("{{|test}}")
@@ -40,6 +41,7 @@ class ParsingQuirksTest < Test::Unit::TestCase
end
def test_meaningless_parens
Template.error_mode = :strict
assert_raise(SyntaxError) do
markup = "a == 'foo' or (b == 'bar' and c == 'baz') or false"
Template.parse("{% if #{markup} %} YES {% endif %}")
@@ -47,6 +49,7 @@ class ParsingQuirksTest < Test::Unit::TestCase
end
def test_unexpected_characters_silently_eat_logic
Template.error_mode = :strict
assert_raise(SyntaxError) do
markup = "true && false"
Template.parse("{% if #{markup} %} YES {% endif %}")