Merge pull request #240 from Shopify/remove_flatten

remove .flatten on standard filters
This commit is contained in:
Arthur Nogueira Neves
2014-07-24 10:54:28 -04:00
3 changed files with 55 additions and 19 deletions
+35 -16
View File
@@ -92,16 +92,16 @@ module Liquid
# Join elements of the array with certain character between them
def join(input, glue = ' '.freeze)
[input].flatten.join(glue)
InputIterator.new(input).join(glue)
end
# Sort elements of the array
# provide optional property with which to sort an array of hashes or drops
def sort(input, property = nil)
ary = flatten_if_necessary(input)
ary = InputIterator.new(input)
if property.nil?
ary.sort
elsif ary.first.respond_to?('[]'.freeze) and !ary.first[property].nil?
elsif ary.first.respond_to?('[]'.freeze) && !ary.first[property].nil?
ary.sort {|a,b| a[property] <=> b[property] }
elsif ary.first.respond_to?(property)
ary.sort {|a,b| a.send(property) <=> b.send(property) }
@@ -110,13 +110,13 @@ module Liquid
# Reverse the elements of an array
def reverse(input)
ary = [input].flatten
ary = InputIterator.new(input)
ary.reverse
end
# map/collect on a given property
def map(input, property)
flatten_if_necessary(input).map do |e|
InputIterator.new(input).map do |e|
e = e.call if e.is_a?(Proc)
if property == "to_liquid".freeze
@@ -265,17 +265,6 @@ module Liquid
private
def flatten_if_necessary(input)
ary = if input.is_a?(Array)
input.flatten
elsif input.is_a?(Enumerable) && !input.is_a?(Hash)
input
else
[input].flatten
end
ary.map{ |e| e.respond_to?(:to_liquid) ? e.to_liquid : e }
end
def to_number(obj)
case obj
when Float
@@ -310,6 +299,36 @@ module Liquid
result = to_number(input).send(operation, to_number(operand))
result.is_a?(BigDecimal) ? result.to_f : result
end
class InputIterator
include Enumerable
def initialize(input)
@input = if input.is_a?(Array)
input.flatten
elsif input.is_a?(Hash)
[input]
elsif input.is_a?(Enumerable)
input
else
Array(input)
end
end
def join(glue)
to_a.join(glue)
end
def reverse
reverse_each.to_a
end
def each
@input.each do |e|
yield(e.respond_to?(:to_liquid) ? e.to_liquid : e)
end
end
end
end
Template.register_filter(StandardFilters)
+2 -2
View File
@@ -67,12 +67,12 @@ class FiltersTest < Test::Unit::TestCase
@context['value'] = 3
@context['numbers'] = [2,1,4,3]
@context['words'] = ['expected', 'as', 'alphabetic']
@context['arrays'] = [['flattened'], ['are']]
@context['arrays'] = ['flower', 'are']
assert_equal [1,2,3,4], Variable.new("numbers | sort").render(@context)
assert_equal ['alphabetic', 'as', 'expected'], Variable.new("words | sort").render(@context)
assert_equal [3], Variable.new("value | sort").render(@context)
assert_equal ['are', 'flattened'], Variable.new("arrays | sort").render(@context)
assert_equal ['are', 'flower'], Variable.new("arrays | sort").render(@context)
end
def test_strip_html
+18 -1
View File
@@ -7,6 +7,8 @@ class Filters
end
class TestThing
attr_reader :foo
def initialize
@foo = 0
end
@@ -115,6 +117,10 @@ class StandardFiltersTest < Test::Unit::TestCase
assert_equal [{"a" => 1}, {"a" => 2}, {"a" => 3}, {"a" => 4}], @filters.sort([{"a" => 4}, {"a" => 3}, {"a" => 1}, {"a" => 2}], "a")
end
def test_legacy_sort_hash
assert_equal [{a:1, b:2}], @filters.sort({a:1, b:2})
end
def test_numerical_vs_lexicographical_sort
assert_equal [2, 10], @filters.sort([10, 2])
assert_equal [{"a" => 2}, {"a" => 10}], @filters.sort([{"a" => 10}, {"a" => 2}], "a")
@@ -126,6 +132,10 @@ class StandardFiltersTest < Test::Unit::TestCase
assert_equal [4,3,2,1], @filters.reverse([1,2,3,4])
end
def test_legacy_reverse_hash
assert_equal [{a:1, b:2}], @filters.reverse(a:1, b:2)
end
def test_map
assert_equal [1,2,3,4], @filters.map([{"a" => 1}, {"a" => 2}, {"a" => 3}, {"a" => 4}], 'a')
assert_template_result 'abc', "{{ ary | map:'foo' | map:'bar' }}",
@@ -147,9 +157,16 @@ class StandardFiltersTest < Test::Unit::TestCase
"thing" => { "foo" => [ { "bar" => 42 }, { "bar" => 17 } ] }
end
def test_legacy_map_on_hashes_with_dynamic_key
template = "{% assign key = 'foo' %}{{ thing | map: key | map: 'bar' }}"
hash = { "foo" => { "bar" => 42 } }
assert_template_result "42", template, "thing" => hash
end
def test_sort_calls_to_liquid
t = TestThing.new
assert_template_result "woot: 1", '{{ foo | sort: "whatever" }}', "foo" => [t]
Liquid::Template.parse('{{ foo | sort: "whatever" }}').render("foo" => [t])
assert t.foo > 0
end
def test_map_over_proc