diff --git a/lib/liquid/expression.rb b/lib/liquid/expression.rb index fdbe382..69c7472 100644 --- a/lib/liquid/expression.rb +++ b/lib/liquid/expression.rb @@ -10,25 +10,28 @@ module Liquid 'empty' => '' }.freeze - SINGLE_QUOTED_STRING = /\A'(.*)'\z/m - DOUBLE_QUOTED_STRING = /\A"(.*)"\z/m - INTEGERS_REGEX = /\A(-?\d+)\z/ - FLOATS_REGEX = /\A(-?\d[\d\.]+)\z/ - RANGES_REGEX = /\A\((\S+)\.\.(\S+)\)\z/ + SINGLE_QUOTED_STRING = /\A\s*'(.*)'\s*\z/m + DOUBLE_QUOTED_STRING = /\A\s*"(.*)"\s*\z/m + INTEGERS_REGEX = /\A\s*(-?\d+)\s*\z/ + FLOATS_REGEX = /\A\s*(-?\d[\d\.]+)\s*\z/ + RANGES_REGEX = /\A\s*\(\s*(\S+)\s*\.\.\s*(\S+)\s*\)\s*\z/ def self.parse(markup) - if LITERALS.key?(markup) - LITERALS[markup] + case markup + when nil + nil + when SINGLE_QUOTED_STRING, DOUBLE_QUOTED_STRING + Regexp.last_match(1) + when INTEGERS_REGEX + Regexp.last_match(1).to_i + when RANGES_REGEX + RangeLookup.parse(Regexp.last_match(1), Regexp.last_match(2)) + when FLOATS_REGEX + Regexp.last_match(1).to_f else - case markup - when SINGLE_QUOTED_STRING, DOUBLE_QUOTED_STRING - Regexp.last_match(1) - when INTEGERS_REGEX - Regexp.last_match(1).to_i - when RANGES_REGEX - RangeLookup.parse(Regexp.last_match(1), Regexp.last_match(2)) - when FLOATS_REGEX - Regexp.last_match(1).to_f + markup = markup.strip + if LITERALS.key?(markup) + LITERALS[markup] else VariableLookup.parse(markup) end diff --git a/test/integration/expression_test.rb b/test/integration/expression_test.rb new file mode 100644 index 0000000..91a0494 --- /dev/null +++ b/test/integration/expression_test.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'test_helper' + +class ExpressionTest < Minitest::Test + def test_keyword_literals + assert_equal(true, parse_and_eval("true")) + assert_equal(true, parse_and_eval(" true ")) + end + + def test_string + assert_equal("single quoted", parse_and_eval("'single quoted'")) + assert_equal("double quoted", parse_and_eval('"double quoted"')) + assert_equal("spaced", parse_and_eval(" 'spaced' ")) + assert_equal("spaced2", parse_and_eval(' "spaced2" ')) + end + + def test_int + assert_equal(123, parse_and_eval("123")) + assert_equal(456, parse_and_eval(" 456 ")) + assert_equal(12, parse_and_eval("012")) + end + + def test_float + assert_equal(1.5, parse_and_eval("1.5")) + assert_equal(2.5, parse_and_eval(" 2.5 ")) + end + + def test_range + assert_equal(1..2, parse_and_eval("(1..2)")) + assert_equal(3..4, parse_and_eval(" ( 3 .. 4 ) ")) + end + + private + + def parse_and_eval(markup, **assigns) + if Liquid::Template.error_mode == :strict + p = Liquid::Parser.new(markup) + markup = p.expression + p.consume(:end_of_string) + end + expression = Liquid::Expression.parse(markup) + context = Liquid::Context.new(assigns) + context.evaluate(expression) + end +end