From 6fb402e60dff5348ce512a2038c16e7ed0234841 Mon Sep 17 00:00:00 2001 From: Justin Li Date: Wed, 8 Jul 2015 17:33:05 -0400 Subject: [PATCH 1/3] Move to_integer, to_date, and to_number to Liquid::Utils --- lib/liquid/standardfilters.rb | 61 ++++++----------------------------- lib/liquid/utils.rb | 43 ++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/lib/liquid/standardfilters.rb b/lib/liquid/standardfilters.rb index 5038acf..dd60c14 100644 --- a/lib/liquid/standardfilters.rb +++ b/lib/liquid/standardfilters.rb @@ -46,8 +46,8 @@ module Liquid end def slice(input, offset, length = nil) - offset = to_integer(offset) - length = length ? to_integer(length) : 1 + offset = Utils.to_integer(offset) + length = length ? Utils.to_integer(length) : 1 if input.is_a?(Array) input.slice(offset, length) || [] @@ -59,7 +59,7 @@ module Liquid # Truncate a string down to x characters def truncate(input, length = 50, truncate_string = "...".freeze) return if input.nil? - length = to_integer(length) + length = Utils.to_integer(length) l = length - truncate_string.length l = 0 if l < 0 input.length > length ? input[0...l] + truncate_string : input @@ -68,7 +68,7 @@ module Liquid def truncatewords(input, words = 15, truncate_string = "...".freeze) return if input.nil? wordlist = input.to_s.split - words = to_integer(words) + words = Utils.to_integer(words) l = words - 1 l = 0 if l < 0 wordlist.length > l ? wordlist[0..l].join(" ".freeze) + truncate_string : input @@ -255,7 +255,7 @@ module Liquid def date(input, format) return input if format.to_s.empty? - return input unless date = to_date(input) + return input unless date = Utils.to_date(input) date.strftime(format.to_s) end @@ -307,7 +307,7 @@ module Liquid end def round(input, n = 0) - result = to_number(input).round(to_number(n)) + result = Utils.to_number(input).round(Utils.to_number(n)) result = result.to_f if result.is_a?(BigDecimal) result = result.to_i if n == 0 result @@ -316,13 +316,13 @@ module Liquid end def ceil(input) - to_number(input).ceil.to_i + Utils.to_number(input).ceil.to_i rescue ::FloatDomainError => e raise Liquid::FloatDomainError, e.message end def floor(input) - to_number(input).floor.to_i + Utils.to_number(input).floor.to_i rescue ::FloatDomainError => e raise Liquid::FloatDomainError, e.message end @@ -334,51 +334,8 @@ module Liquid private - def to_integer(num) - return num if num.is_a?(Integer) - num = num.to_s - begin - Integer(num) - rescue ::ArgumentError - raise Liquid::ArgumentError, "invalid integer" - end - end - - def to_number(obj) - case obj - when Float - BigDecimal.new(obj.to_s) - when Numeric - obj - when String - (obj.strip =~ /\A\d+\.\d+\z/) ? BigDecimal.new(obj) : obj.to_i - else - 0 - end - end - - def to_date(obj) - return obj if obj.respond_to?(:strftime) - - if obj.is_a?(String) - return nil if obj.empty? - obj = obj.downcase - end - - case obj - when 'now'.freeze, 'today'.freeze - Time.now - when /\A\d+\z/, Integer - Time.at(obj.to_i) - when String - Time.parse(obj) - end - rescue ArgumentError - nil - end - def apply_operation(input, operand, operation) - result = to_number(input).send(operation, to_number(operand)) + result = Utils.to_number(input).send(operation, Utils.to_number(operand)) result.is_a?(BigDecimal) ? result.to_f : result end diff --git a/lib/liquid/utils.rb b/lib/liquid/utils.rb index ba8a2ca..7725ff8 100644 --- a/lib/liquid/utils.rb +++ b/lib/liquid/utils.rb @@ -32,5 +32,48 @@ module Liquid segments end + + def self.to_integer(num) + return num if num.is_a?(Integer) + num = num.to_s + begin + Integer(num) + rescue ::ArgumentError + raise Liquid::ArgumentError, "invalid integer" + end + end + + def self.to_number(obj) + case obj + when Float + BigDecimal.new(obj.to_s) + when Numeric + obj + when String + (obj.strip =~ /\A\d+\.\d+\z/) ? BigDecimal.new(obj) : obj.to_i + else + 0 + end + end + + def self.to_date(obj) + return obj if obj.respond_to?(:strftime) + + if obj.is_a?(String) + return nil if obj.empty? + obj = obj.downcase + end + + case obj + when 'now'.freeze, 'today'.freeze + Time.now + when /\A\d+\z/, Integer + Time.at(obj.to_i) + when String + Time.parse(obj) + end + rescue ArgumentError + nil + end end end From 83b6dd02686077752cfafc50a50ced91cf4a1ccb Mon Sep 17 00:00:00 2001 From: Justin Li Date: Wed, 8 Jul 2015 17:37:07 -0400 Subject: [PATCH 2/3] Use to_integer for range lookup arguments --- lib/liquid/range_lookup.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/liquid/range_lookup.rb b/lib/liquid/range_lookup.rb index efebd2c..8da022d 100644 --- a/lib/liquid/range_lookup.rb +++ b/lib/liquid/range_lookup.rb @@ -16,7 +16,9 @@ module Liquid end def evaluate(context) - context.evaluate(@start_obj).to_i..context.evaluate(@end_obj).to_i + start_int = Utils.to_integer(context.evaluate(@start_obj)) + end_int = Utils.to_integer(context.evaluate(@end_obj)) + start_int..end_int end end end From 4c1b89e20ee444f5e7aa235972654d8a46fe2776 Mon Sep 17 00:00:00 2001 From: Justin Li Date: Wed, 8 Jul 2015 17:41:18 -0400 Subject: [PATCH 3/3] Add regression test for ranges on non-integer types --- test/integration/tags/for_tag_test.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/integration/tags/for_tag_test.rb b/test/integration/tags/for_tag_test.rb index 624a9de..fe2779f 100644 --- a/test/integration/tags/for_tag_test.rb +++ b/test/integration/tags/for_tag_test.rb @@ -38,6 +38,10 @@ HERE def test_for_with_range assert_template_result(' 1 2 3 ', '{%for item in (1..3) %} {{item}} {%endfor%}') + + assert_raises(Liquid::ArgumentError) do + Template.parse('{% for i in (a..2) %}{% endfor %}').render!("a" => [1, 2]) + end end def test_for_with_variable_range