mirror of
https://github.com/kemko/liquid.git
synced 2026-01-03 16:55:40 +03:00
Compare commits
6 Commits
fix/echo-p
...
pz-strict-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
351e8f3fff | ||
|
|
2cf4b1bd55 | ||
|
|
38600338cf | ||
|
|
6d19a56ef3 | ||
|
|
2c27c2a6e1 | ||
|
|
933a1f1e7e |
@@ -49,6 +49,14 @@ module Liquid
|
|||||||
@@method_literals[markup] || parse_context.parse_expression(markup)
|
@@method_literals[markup] || parse_context.parse_expression(markup)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.strict_parse_expression(parse_context, p)
|
||||||
|
if p.look(:id) && !p.look(:dot, 1) && !p.look(:open_square, 1)
|
||||||
|
parse_expression(parse_context, p.consume)
|
||||||
|
else
|
||||||
|
p.expression
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
attr_reader :attachment, :child_condition
|
attr_reader :attachment, :child_condition
|
||||||
attr_accessor :left, :operator, :right
|
attr_accessor :left, :operator, :right
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ module Liquid
|
|||||||
if LITERALS.key?(markup)
|
if LITERALS.key?(markup)
|
||||||
LITERALS[markup]
|
LITERALS[markup]
|
||||||
else
|
else
|
||||||
VariableLookup.parse(markup)
|
VariableLookup.lax_parse(markup)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -50,53 +50,52 @@ module Liquid
|
|||||||
token = @tokens[@p]
|
token = @tokens[@p]
|
||||||
case token[0]
|
case token[0]
|
||||||
when :id
|
when :id
|
||||||
str = consume
|
if Expression::LITERALS.key?(token[1]) && !look(:dot, 1) && !look(:open_square, 1)
|
||||||
str << variable_lookups
|
Expression::LITERALS[consume]
|
||||||
|
else
|
||||||
|
VariableLookup.strict_parse(self)
|
||||||
|
end
|
||||||
when :open_square
|
when :open_square
|
||||||
str = consume
|
VariableLookup.strict_parse(self)
|
||||||
str << expression
|
when :string
|
||||||
str << consume(:close_square)
|
consume[1..-2]
|
||||||
str << variable_lookups
|
when :number
|
||||||
when :string, :number
|
num_str = consume
|
||||||
consume
|
num_str.include?('.') ? num_str.to_f : num_str.to_i
|
||||||
when :open_round
|
when :open_round
|
||||||
consume
|
consume
|
||||||
first = expression
|
first = expression
|
||||||
consume(:dotdot)
|
consume(:dotdot)
|
||||||
last = expression
|
last = expression
|
||||||
consume(:close_round)
|
consume(:close_round)
|
||||||
"(#{first}..#{last})"
|
RangeLookup.build(first, last)
|
||||||
else
|
else
|
||||||
raise SyntaxError, "#{token} is not a valid expression"
|
raise SyntaxError, "#{token} is not a valid expression"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def argument
|
def arguments
|
||||||
str = +""
|
filter_args = []
|
||||||
# might be a keyword argument (identifier: expression)
|
keyword_args = nil
|
||||||
if look(:id) && look(:colon, 1)
|
|
||||||
str << consume << consume << ' '
|
|
||||||
end
|
|
||||||
|
|
||||||
str << expression
|
|
||||||
str
|
|
||||||
end
|
|
||||||
|
|
||||||
def variable_lookups
|
|
||||||
str = +""
|
|
||||||
loop do
|
loop do
|
||||||
if look(:open_square)
|
# keyword argument (identifier: expression)
|
||||||
str << consume
|
if look(:colon, 1)
|
||||||
str << expression
|
keyword_args ||= {}
|
||||||
str << consume(:close_square)
|
k = consume(:id)
|
||||||
elsif look(:dot)
|
consume
|
||||||
str << consume
|
v = expression
|
||||||
str << consume(:id)
|
keyword_args[k] = v
|
||||||
else
|
else
|
||||||
break
|
filter_args << expression
|
||||||
end
|
end
|
||||||
|
|
||||||
|
break unless consume?(:comma)
|
||||||
end
|
end
|
||||||
str
|
|
||||||
|
result = [filter_args]
|
||||||
|
result << keyword_args if keyword_args
|
||||||
|
result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,35 +5,43 @@ module Liquid
|
|||||||
def self.parse(start_markup, end_markup)
|
def self.parse(start_markup, end_markup)
|
||||||
start_obj = Expression.parse(start_markup)
|
start_obj = Expression.parse(start_markup)
|
||||||
end_obj = Expression.parse(end_markup)
|
end_obj = Expression.parse(end_markup)
|
||||||
|
build(start_obj, end_obj)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.build(start_obj, end_obj)
|
||||||
if start_obj.respond_to?(:evaluate) || end_obj.respond_to?(:evaluate)
|
if start_obj.respond_to?(:evaluate) || end_obj.respond_to?(:evaluate)
|
||||||
new(start_obj, end_obj)
|
new(start_obj, end_obj)
|
||||||
else
|
else
|
||||||
start_obj.to_i..end_obj.to_i
|
to_integer(start_obj)..to_integer(end_obj)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(start_obj, end_obj)
|
def self.to_integer(input)
|
||||||
@start_obj = start_obj
|
|
||||||
@end_obj = end_obj
|
|
||||||
end
|
|
||||||
|
|
||||||
def evaluate(context)
|
|
||||||
start_int = to_integer(context.evaluate(@start_obj))
|
|
||||||
end_int = to_integer(context.evaluate(@end_obj))
|
|
||||||
start_int..end_int
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def to_integer(input)
|
|
||||||
case input
|
case input
|
||||||
when Integer
|
when Integer
|
||||||
input
|
input
|
||||||
when NilClass, String
|
when NilClass, String, Float
|
||||||
input.to_i
|
input.to_i
|
||||||
else
|
else
|
||||||
Utils.to_integer(input)
|
Utils.to_integer(input)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
attr_reader :start_expr, :end_expr
|
||||||
|
|
||||||
|
def initialize(start_expr, end_expr)
|
||||||
|
@start_expr = start_expr
|
||||||
|
@end_expr = end_expr
|
||||||
|
end
|
||||||
|
|
||||||
|
def evaluate(context)
|
||||||
|
start_int = self.class.to_integer(context.evaluate(@start_expr))
|
||||||
|
end_int = self.class.to_integer(context.evaluate(@end_expr))
|
||||||
|
start_int..end_int
|
||||||
|
end
|
||||||
|
|
||||||
|
def ==(other)
|
||||||
|
self.class == other.class && start_expr == other.start_expr && end_expr == other.end_expr
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -113,10 +113,9 @@ module Liquid
|
|||||||
@variable_name = p.consume(:id)
|
@variable_name = p.consume(:id)
|
||||||
raise SyntaxError, options[:locale].t("errors.syntax.for_invalid_in") unless p.id?('in')
|
raise SyntaxError, options[:locale].t("errors.syntax.for_invalid_in") unless p.id?('in')
|
||||||
|
|
||||||
collection_name = p.expression
|
@collection_name = p.expression
|
||||||
@collection_name = parse_expression(collection_name)
|
|
||||||
|
|
||||||
@name = "#{@variable_name}-#{collection_name}"
|
@name = "#{@variable_name}-#{@collection_name}"
|
||||||
@reversed = p.id?('reversed')
|
@reversed = p.id?('reversed')
|
||||||
|
|
||||||
while p.look(:id) && p.look(:colon, 1)
|
while p.look(:id) && p.look(:colon, 1)
|
||||||
@@ -124,7 +123,18 @@ module Liquid
|
|||||||
raise SyntaxError, options[:locale].t("errors.syntax.for_invalid_attribute")
|
raise SyntaxError, options[:locale].t("errors.syntax.for_invalid_attribute")
|
||||||
end
|
end
|
||||||
p.consume
|
p.consume
|
||||||
set_attribute(attribute, p.expression)
|
case attribute
|
||||||
|
when 'offset'
|
||||||
|
@from =
|
||||||
|
if p.id?('continue')
|
||||||
|
Usage.increment('for_offset_continue')
|
||||||
|
:continue
|
||||||
|
else
|
||||||
|
p.expression
|
||||||
|
end
|
||||||
|
when 'limit'
|
||||||
|
@limit = p.expression
|
||||||
|
end
|
||||||
end
|
end
|
||||||
p.consume(:end_of_string)
|
p.consume(:end_of_string)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -75,6 +75,10 @@ module Liquid
|
|||||||
Condition.parse_expression(parse_context, markup)
|
Condition.parse_expression(parse_context, markup)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def strict_parse_expression(p)
|
||||||
|
Condition.strict_parse_expression(parse_context, p)
|
||||||
|
end
|
||||||
|
|
||||||
def lax_parse(markup)
|
def lax_parse(markup)
|
||||||
expressions = markup.scan(ExpressionsAndOperators)
|
expressions = markup.scan(ExpressionsAndOperators)
|
||||||
raise SyntaxError, options[:locale].t("errors.syntax.if") unless expressions.pop =~ Syntax
|
raise SyntaxError, options[:locale].t("errors.syntax.if") unless expressions.pop =~ Syntax
|
||||||
@@ -114,9 +118,9 @@ module Liquid
|
|||||||
end
|
end
|
||||||
|
|
||||||
def parse_comparison(p)
|
def parse_comparison(p)
|
||||||
a = parse_expression(p.expression)
|
a = strict_parse_expression(p)
|
||||||
if (op = p.consume?(:comparison))
|
if (op = p.consume?(:comparison))
|
||||||
b = parse_expression(p.expression)
|
b = strict_parse_expression(p)
|
||||||
Condition.new(a, op, b)
|
Condition.new(a, op, b)
|
||||||
else
|
else
|
||||||
Condition.new(a)
|
Condition.new(a)
|
||||||
|
|||||||
@@ -65,23 +65,15 @@ module Liquid
|
|||||||
|
|
||||||
return if p.look(:end_of_string)
|
return if p.look(:end_of_string)
|
||||||
|
|
||||||
@name = Expression.parse(p.expression)
|
@name = p.expression
|
||||||
while p.consume?(:pipe)
|
while p.consume?(:pipe)
|
||||||
filtername = p.consume(:id)
|
filtername = p.consume(:id)
|
||||||
filterargs = p.consume?(:colon) ? parse_filterargs(p) : []
|
filterargs = p.consume?(:colon) ? p.arguments : [[]]
|
||||||
@filters << parse_filter_expressions(filtername, filterargs)
|
@filters << [filtername, *filterargs]
|
||||||
end
|
end
|
||||||
p.consume(:end_of_string)
|
p.consume(:end_of_string)
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_filterargs(p)
|
|
||||||
# first argument
|
|
||||||
filterargs = [p.argument]
|
|
||||||
# followed by comma separated others
|
|
||||||
filterargs << p.argument while p.consume?(:comma)
|
|
||||||
filterargs
|
|
||||||
end
|
|
||||||
|
|
||||||
def render(context)
|
def render(context)
|
||||||
obj = context.evaluate(@name)
|
obj = context.evaluate(@name)
|
||||||
|
|
||||||
|
|||||||
@@ -7,30 +7,66 @@ module Liquid
|
|||||||
|
|
||||||
attr_reader :name, :lookups
|
attr_reader :name, :lookups
|
||||||
|
|
||||||
def self.parse(markup)
|
class << self
|
||||||
new(markup)
|
def lax_parse(markup)
|
||||||
|
lookups = markup.scan(VariableParser)
|
||||||
|
|
||||||
|
name = lookups.shift
|
||||||
|
if name =~ SQUARE_BRACKETED
|
||||||
|
name = Expression.parse(Regexp.last_match(1))
|
||||||
|
end
|
||||||
|
|
||||||
|
command_flags = 0
|
||||||
|
|
||||||
|
lookups.each_index do |i|
|
||||||
|
lookup = lookups[i]
|
||||||
|
if lookup =~ SQUARE_BRACKETED
|
||||||
|
lookups[i] = Expression.parse(Regexp.last_match(1))
|
||||||
|
elsif COMMAND_METHODS.include?(lookup)
|
||||||
|
command_flags |= 1 << i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
new(name, lookups, command_flags)
|
||||||
|
end
|
||||||
|
|
||||||
|
def strict_parse(p)
|
||||||
|
if p.look(:id)
|
||||||
|
name = p.consume
|
||||||
|
else
|
||||||
|
p.consume(:open_square)
|
||||||
|
name = p.expression
|
||||||
|
p.consume(:close_square)
|
||||||
|
end
|
||||||
|
|
||||||
|
lookups = []
|
||||||
|
command_flags = 0
|
||||||
|
|
||||||
|
loop do
|
||||||
|
if p.consume?(:open_square)
|
||||||
|
lookups << p.expression
|
||||||
|
p.consume(:close_square)
|
||||||
|
elsif p.consume?(:dot)
|
||||||
|
lookup = p.consume(:id)
|
||||||
|
lookups << lookup
|
||||||
|
if COMMAND_METHODS.include?(lookup)
|
||||||
|
command_flags |= 1 << (lookups.length - 1)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
new(name, lookups, command_flags)
|
||||||
|
end
|
||||||
|
|
||||||
|
private :new
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(markup)
|
def initialize(name, lookups, command_flags)
|
||||||
lookups = markup.scan(VariableParser)
|
|
||||||
|
|
||||||
name = lookups.shift
|
|
||||||
if name =~ SQUARE_BRACKETED
|
|
||||||
name = Expression.parse(Regexp.last_match(1))
|
|
||||||
end
|
|
||||||
@name = name
|
@name = name
|
||||||
|
@lookups = lookups
|
||||||
@lookups = lookups
|
@command_flags = command_flags
|
||||||
@command_flags = 0
|
|
||||||
|
|
||||||
@lookups.each_index do |i|
|
|
||||||
lookup = lookups[i]
|
|
||||||
if lookup =~ SQUARE_BRACKETED
|
|
||||||
lookups[i] = Expression.parse(Regexp.last_match(1))
|
|
||||||
elsif COMMAND_METHODS.include?(lookup)
|
|
||||||
@command_flags |= 1 << i
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def evaluate(context)
|
def evaluate(context)
|
||||||
@@ -75,6 +111,19 @@ module Liquid
|
|||||||
self.class == other.class && state == other.state
|
self.class == other.class && state == other.state
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
str = name.dup
|
||||||
|
lookups.each do |lookup|
|
||||||
|
str +=
|
||||||
|
if lookup.instance_of?(String)
|
||||||
|
"['#{lookup}']"
|
||||||
|
else
|
||||||
|
"[#{lookup}]"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
str
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def state
|
def state
|
||||||
|
|||||||
@@ -29,17 +29,24 @@ class ExpressionTest < Minitest::Test
|
|||||||
def test_range
|
def test_range
|
||||||
assert_equal(1..2, parse_and_eval("(1..2)"))
|
assert_equal(1..2, parse_and_eval("(1..2)"))
|
||||||
assert_equal(3..4, parse_and_eval(" ( 3 .. 4 ) "))
|
assert_equal(3..4, parse_and_eval(" ( 3 .. 4 ) "))
|
||||||
|
assert_equal(0..0, parse_and_eval("('a'..'b')"))
|
||||||
|
|
||||||
|
with_error_mode(:strict) do
|
||||||
|
assert_raises(Liquid::ArgumentError) { parse_and_eval("(1..(1..5))") }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def parse_and_eval(markup, **assigns)
|
def parse_and_eval(markup, **assigns)
|
||||||
if Liquid::Template.error_mode == :strict
|
expression =
|
||||||
p = Liquid::Parser.new(markup)
|
if Liquid::Template.error_mode == :strict
|
||||||
markup = p.expression
|
p = Liquid::Parser.new(markup)
|
||||||
p.consume(:end_of_string)
|
p.expression
|
||||||
end
|
else
|
||||||
expression = Liquid::Expression.parse(markup)
|
Liquid::Expression.parse(markup)
|
||||||
|
end
|
||||||
|
|
||||||
context = Liquid::Context.new(assigns)
|
context = Liquid::Context.new(assigns)
|
||||||
context.evaluate(expression)
|
context.evaluate(expression)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ class ConditionUnitTest < Minitest::Test
|
|||||||
def test_contains_works_on_arrays
|
def test_contains_works_on_arrays
|
||||||
@context = Liquid::Context.new
|
@context = Liquid::Context.new
|
||||||
@context['array'] = [1, 2, 3, 4, 5]
|
@context['array'] = [1, 2, 3, 4, 5]
|
||||||
array_expr = VariableLookup.new("array")
|
array_expr = parse_variable_lookup("array")
|
||||||
|
|
||||||
assert_evaluates_false(array_expr, 'contains', 0)
|
assert_evaluates_false(array_expr, 'contains', 0)
|
||||||
assert_evaluates_true(array_expr, 'contains', 1)
|
assert_evaluates_true(array_expr, 'contains', 1)
|
||||||
@@ -91,8 +91,8 @@ class ConditionUnitTest < Minitest::Test
|
|||||||
|
|
||||||
def test_contains_returns_false_for_nil_operands
|
def test_contains_returns_false_for_nil_operands
|
||||||
@context = Liquid::Context.new
|
@context = Liquid::Context.new
|
||||||
assert_evaluates_false(VariableLookup.new('not_assigned'), 'contains', '0')
|
assert_evaluates_false(parse_variable_lookup('not_assigned'), 'contains', '0')
|
||||||
assert_evaluates_false(0, 'contains', VariableLookup.new('not_assigned'))
|
assert_evaluates_false(0, 'contains', parse_variable_lookup('not_assigned'))
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_contains_return_false_on_wrong_data_type
|
def test_contains_return_false_on_wrong_data_type
|
||||||
@@ -145,11 +145,20 @@ class ConditionUnitTest < Minitest::Test
|
|||||||
@context = Liquid::Context.new
|
@context = Liquid::Context.new
|
||||||
@context['one'] = @context['another'] = "gnomeslab-and-or-liquid"
|
@context['one'] = @context['another'] = "gnomeslab-and-or-liquid"
|
||||||
|
|
||||||
assert_evaluates_true(VariableLookup.new("one"), '==', VariableLookup.new("another"))
|
assert_evaluates_true(parse_variable_lookup("one"), '==', parse_variable_lookup("another"))
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def parse_variable_lookup(markup)
|
||||||
|
if Liquid::Template.error_mode == :strict
|
||||||
|
p = Liquid::Parser.new(markup)
|
||||||
|
VariableLookup.strict_parse(p)
|
||||||
|
else
|
||||||
|
VariableLookup.lax_parse(markup)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def assert_evaluates_true(left, op, right)
|
def assert_evaluates_true(left, op, right)
|
||||||
assert(Condition.new(left, op, right).evaluate(@context),
|
assert(Condition.new(left, op, right).evaluate(@context),
|
||||||
"Evaluated false: #{left} #{op} #{right}")
|
"Evaluated false: #{left} #{op} #{right}")
|
||||||
|
|||||||
@@ -47,32 +47,41 @@ class ParserUnitTest < Minitest::Test
|
|||||||
|
|
||||||
def test_expressions
|
def test_expressions
|
||||||
p = Parser.new("hi.there hi?[5].there? hi.there.bob")
|
p = Parser.new("hi.there hi?[5].there? hi.there.bob")
|
||||||
assert_equal('hi.there', p.expression)
|
assert_equal(VariableLookup.send(:new, 'hi', ['there'], 0), p.expression)
|
||||||
assert_equal('hi?[5].there?', p.expression)
|
assert_equal(VariableLookup.send(:new, 'hi?', [5, 'there?'], 0), p.expression)
|
||||||
assert_equal('hi.there.bob', p.expression)
|
assert_equal(VariableLookup.send(:new, 'hi', ['there', 'bob'], 0), p.expression)
|
||||||
|
|
||||||
|
p = Parser.new("nil true false")
|
||||||
|
assert_nil(p.expression)
|
||||||
|
assert_equal(true, p.expression)
|
||||||
|
assert_equal(false, p.expression)
|
||||||
|
|
||||||
p = Parser.new("567 6.0 'lol' \"wut\"")
|
p = Parser.new("567 6.0 'lol' \"wut\"")
|
||||||
assert_equal('567', p.expression)
|
assert_equal(567, p.expression)
|
||||||
assert_equal('6.0', p.expression)
|
assert_equal(6.0, p.expression)
|
||||||
assert_equal("'lol'", p.expression)
|
assert_equal('lol', p.expression)
|
||||||
assert_equal('"wut"', p.expression)
|
assert_equal('wut', p.expression)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_ranges
|
def test_ranges
|
||||||
p = Parser.new("(5..7) (1.5..9.6) (young..old) (hi[5].wat..old)")
|
p = Parser.new("(5..7) (1.5..9.6) (young..old) (hi[5].wat..old)")
|
||||||
assert_equal('(5..7)', p.expression)
|
assert_equal(5..7, p.expression)
|
||||||
assert_equal('(1.5..9.6)', p.expression)
|
assert_equal(1..9, p.expression)
|
||||||
assert_equal('(young..old)', p.expression)
|
assert_equal(
|
||||||
assert_equal('(hi[5].wat..old)', p.expression)
|
RangeLookup.new(VariableLookup.send(:new, 'young', [], 0), VariableLookup.send(:new, 'old', [], 0)),
|
||||||
|
p.expression
|
||||||
|
)
|
||||||
|
assert_equal(
|
||||||
|
RangeLookup.new(VariableLookup.send(:new, 'hi', [5, "wat"], 0), VariableLookup.send(:new, 'old', [], 0)),
|
||||||
|
p.expression
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_arguments
|
def test_arguments
|
||||||
p = Parser.new("filter: hi.there[5], keyarg: 7")
|
p = Parser.new("filter: hi.there[5], keyarg: 7")
|
||||||
assert_equal('filter', p.consume(:id))
|
assert_equal('filter', p.consume(:id))
|
||||||
assert_equal(':', p.consume(:colon))
|
assert_equal(':', p.consume(:colon))
|
||||||
assert_equal('hi.there[5]', p.argument)
|
assert_equal([[VariableLookup.send(:new, "hi", ["there", 5], 0)], { "keyarg" => 7 }], p.arguments)
|
||||||
assert_equal(',', p.consume(:comma))
|
|
||||||
assert_equal('keyarg: 7', p.argument)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_invalid_expression
|
def test_invalid_expression
|
||||||
|
|||||||
39
test/unit/variable_lookup_unit_test.rb
Normal file
39
test/unit/variable_lookup_unit_test.rb
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class VariableLookupUnitTest < Minitest::Test
|
||||||
|
include Liquid
|
||||||
|
|
||||||
|
def test_variable_lookup_parsing
|
||||||
|
lookup = parse_variable_lookup('a.b.c')
|
||||||
|
assert_equal('a', lookup.name)
|
||||||
|
assert_equal(['b', 'c'], lookup.lookups)
|
||||||
|
|
||||||
|
lookup = parse_variable_lookup('a[b]')
|
||||||
|
assert_equal('a', lookup.name)
|
||||||
|
assert_equal([parse_variable_lookup('b')], lookup.lookups)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_to_s
|
||||||
|
lookup = parse_variable_lookup('a.b.c')
|
||||||
|
assert_equal("a['b']['c']", lookup.to_s)
|
||||||
|
|
||||||
|
lookup = parse_variable_lookup('a[b.c].d')
|
||||||
|
assert_equal("a[b['c']]['d']", lookup.to_s)
|
||||||
|
|
||||||
|
lookup = parse_variable_lookup('a["foo.bar"].d')
|
||||||
|
assert_equal("a['foo.bar']['d']", lookup.to_s)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def parse_variable_lookup(markup)
|
||||||
|
if Liquid::Template.error_mode == :strict
|
||||||
|
p = Liquid::Parser.new(markup)
|
||||||
|
VariableLookup.strict_parse(p)
|
||||||
|
else
|
||||||
|
VariableLookup.lax_parse(markup)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -7,20 +7,20 @@ class VariableUnitTest < Minitest::Test
|
|||||||
|
|
||||||
def test_variable
|
def test_variable
|
||||||
var = create_variable('hello')
|
var = create_variable('hello')
|
||||||
assert_equal(VariableLookup.new('hello'), var.name)
|
assert_equal(parse_variable_lookup('hello'), var.name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_filters
|
def test_filters
|
||||||
var = create_variable('hello | textileze')
|
var = create_variable('hello | textileze')
|
||||||
assert_equal(VariableLookup.new('hello'), var.name)
|
assert_equal(parse_variable_lookup('hello'), var.name)
|
||||||
assert_equal([['textileze', []]], var.filters)
|
assert_equal([['textileze', []]], var.filters)
|
||||||
|
|
||||||
var = create_variable('hello | textileze | paragraph')
|
var = create_variable('hello | textileze | paragraph')
|
||||||
assert_equal(VariableLookup.new('hello'), var.name)
|
assert_equal(parse_variable_lookup('hello'), var.name)
|
||||||
assert_equal([['textileze', []], ['paragraph', []]], var.filters)
|
assert_equal([['textileze', []], ['paragraph', []]], var.filters)
|
||||||
|
|
||||||
var = create_variable(%( hello | strftime: '%Y'))
|
var = create_variable(%( hello | strftime: '%Y'))
|
||||||
assert_equal(VariableLookup.new('hello'), var.name)
|
assert_equal(parse_variable_lookup('hello'), var.name)
|
||||||
assert_equal([['strftime', ['%Y']]], var.filters)
|
assert_equal([['strftime', ['%Y']]], var.filters)
|
||||||
|
|
||||||
var = create_variable(%( 'typo' | link_to: 'Typo', true ))
|
var = create_variable(%( 'typo' | link_to: 'Typo', true ))
|
||||||
@@ -44,11 +44,11 @@ class VariableUnitTest < Minitest::Test
|
|||||||
assert_equal([['repeat', [3, 3, 3]]], var.filters)
|
assert_equal([['repeat', [3, 3, 3]]], var.filters)
|
||||||
|
|
||||||
var = create_variable(%( hello | strftime: '%Y, okay?'))
|
var = create_variable(%( hello | strftime: '%Y, okay?'))
|
||||||
assert_equal(VariableLookup.new('hello'), var.name)
|
assert_equal(parse_variable_lookup('hello'), var.name)
|
||||||
assert_equal([['strftime', ['%Y, okay?']]], var.filters)
|
assert_equal([['strftime', ['%Y, okay?']]], var.filters)
|
||||||
|
|
||||||
var = create_variable(%( hello | things: "%Y, okay?", 'the other one'))
|
var = create_variable(%( hello | things: "%Y, okay?", 'the other one'))
|
||||||
assert_equal(VariableLookup.new('hello'), var.name)
|
assert_equal(parse_variable_lookup('hello'), var.name)
|
||||||
assert_equal([['things', ['%Y, okay?', 'the other one']]], var.filters)
|
assert_equal([['things', ['%Y, okay?', 'the other one']]], var.filters)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -60,22 +60,24 @@ class VariableUnitTest < Minitest::Test
|
|||||||
|
|
||||||
def test_filters_without_whitespace
|
def test_filters_without_whitespace
|
||||||
var = create_variable('hello | textileze | paragraph')
|
var = create_variable('hello | textileze | paragraph')
|
||||||
assert_equal(VariableLookup.new('hello'), var.name)
|
assert_equal(parse_variable_lookup('hello'), var.name)
|
||||||
assert_equal([['textileze', []], ['paragraph', []]], var.filters)
|
assert_equal([['textileze', []], ['paragraph', []]], var.filters)
|
||||||
|
|
||||||
var = create_variable('hello|textileze|paragraph')
|
var = create_variable('hello|textileze|paragraph')
|
||||||
assert_equal(VariableLookup.new('hello'), var.name)
|
assert_equal(parse_variable_lookup('hello'), var.name)
|
||||||
assert_equal([['textileze', []], ['paragraph', []]], var.filters)
|
assert_equal([['textileze', []], ['paragraph', []]], var.filters)
|
||||||
|
|
||||||
var = create_variable("hello|replace:'foo','bar'|textileze")
|
var = create_variable("hello|replace:'foo','bar'|textileze")
|
||||||
assert_equal(VariableLookup.new('hello'), var.name)
|
assert_equal(parse_variable_lookup('hello'), var.name)
|
||||||
assert_equal([['replace', ['foo', 'bar']], ['textileze', []]], var.filters)
|
assert_equal([['replace', ['foo', 'bar']], ['textileze', []]], var.filters)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_symbol
|
def test_symbol
|
||||||
var = create_variable("http://disney.com/logo.gif | image: 'med' ", error_mode: :lax)
|
with_error_mode(:lax) do
|
||||||
assert_equal(VariableLookup.new('http://disney.com/logo.gif'), var.name)
|
var = create_variable("http://disney.com/logo.gif | image: 'med' ", error_mode: :lax)
|
||||||
assert_equal([['image', ['med']]], var.filters)
|
assert_equal(parse_variable_lookup('http://disney.com/logo.gif'), var.name)
|
||||||
|
assert_equal([['image', ['med']]], var.filters)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_string_to_filter
|
def test_string_to_filter
|
||||||
@@ -105,8 +107,8 @@ class VariableUnitTest < Minitest::Test
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_dashes
|
def test_dashes
|
||||||
assert_equal(VariableLookup.new('foo-bar'), create_variable('foo-bar').name)
|
assert_equal(parse_variable_lookup('foo-bar'), create_variable('foo-bar').name)
|
||||||
assert_equal(VariableLookup.new('foo-bar-2'), create_variable('foo-bar-2').name)
|
assert_equal(parse_variable_lookup('foo-bar-2'), create_variable('foo-bar-2').name)
|
||||||
|
|
||||||
with_error_mode :strict do
|
with_error_mode :strict do
|
||||||
assert_raises(Liquid::SyntaxError) { create_variable('foo - bar') }
|
assert_raises(Liquid::SyntaxError) { create_variable('foo - bar') }
|
||||||
@@ -122,18 +124,18 @@ class VariableUnitTest < Minitest::Test
|
|||||||
|
|
||||||
def test_string_dot
|
def test_string_dot
|
||||||
var = create_variable(%( test.test ))
|
var = create_variable(%( test.test ))
|
||||||
assert_equal(VariableLookup.new('test.test'), var.name)
|
assert_equal(parse_variable_lookup('test.test'), var.name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_filter_with_keyword_arguments
|
def test_filter_with_keyword_arguments
|
||||||
var = create_variable(%( hello | things: greeting: "world", farewell: 'goodbye'))
|
var = create_variable(%( hello | things: greeting: "world", farewell: 'goodbye'))
|
||||||
assert_equal(VariableLookup.new('hello'), var.name)
|
assert_equal(parse_variable_lookup('hello'), var.name)
|
||||||
assert_equal([['things', [], { 'greeting' => 'world', 'farewell' => 'goodbye' }]], var.filters)
|
assert_equal([['things', [], { 'greeting' => 'world', 'farewell' => 'goodbye' }]], var.filters)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_lax_filter_argument_parsing
|
def test_lax_filter_argument_parsing
|
||||||
var = create_variable(%( number_of_comments | pluralize: 'comment': 'comments' ), error_mode: :lax)
|
var = create_variable(%( number_of_comments | pluralize: 'comment': 'comments' ), error_mode: :lax)
|
||||||
assert_equal(VariableLookup.new('number_of_comments'), var.name)
|
assert_equal(parse_variable_lookup('number_of_comments'), var.name)
|
||||||
assert_equal([['pluralize', ['comment', 'comments']]], var.filters)
|
assert_equal([['pluralize', ['comment', 'comments']]], var.filters)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -150,14 +152,17 @@ class VariableUnitTest < Minitest::Test
|
|||||||
assert_equal(" name_of_variable | upcase ", var.raw)
|
assert_equal(" name_of_variable | upcase ", var.raw)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_variable_lookup_interface
|
|
||||||
lookup = VariableLookup.new('a.b.c')
|
|
||||||
assert_equal('a', lookup.name)
|
|
||||||
assert_equal(['b', 'c'], lookup.lookups)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def parse_variable_lookup(markup)
|
||||||
|
if Liquid::Template.error_mode == :strict
|
||||||
|
p = Liquid::Parser.new(markup)
|
||||||
|
VariableLookup.strict_parse(p)
|
||||||
|
else
|
||||||
|
VariableLookup.lax_parse(markup)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def create_variable(markup, options = {})
|
def create_variable(markup, options = {})
|
||||||
Variable.new(markup, ParseContext.new(options))
|
Variable.new(markup, ParseContext.new(options))
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user