mirror of
https://github.com/Shopify/liquid.git
synced 2026-09-12 23:40:45 -07:00
Merge pull request #240 from Shopify/remove_flatten
remove .flatten on standard filters
This commit is contained in:
@@ -92,16 +92,16 @@ module Liquid
|
|||||||
|
|
||||||
# Join elements of the array with certain character between them
|
# Join elements of the array with certain character between them
|
||||||
def join(input, glue = ' '.freeze)
|
def join(input, glue = ' '.freeze)
|
||||||
[input].flatten.join(glue)
|
InputIterator.new(input).join(glue)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sort elements of the array
|
# Sort elements of the array
|
||||||
# provide optional property with which to sort an array of hashes or drops
|
# provide optional property with which to sort an array of hashes or drops
|
||||||
def sort(input, property = nil)
|
def sort(input, property = nil)
|
||||||
ary = flatten_if_necessary(input)
|
ary = InputIterator.new(input)
|
||||||
if property.nil?
|
if property.nil?
|
||||||
ary.sort
|
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] }
|
ary.sort {|a,b| a[property] <=> b[property] }
|
||||||
elsif ary.first.respond_to?(property)
|
elsif ary.first.respond_to?(property)
|
||||||
ary.sort {|a,b| a.send(property) <=> b.send(property) }
|
ary.sort {|a,b| a.send(property) <=> b.send(property) }
|
||||||
@@ -110,13 +110,13 @@ module Liquid
|
|||||||
|
|
||||||
# Reverse the elements of an array
|
# Reverse the elements of an array
|
||||||
def reverse(input)
|
def reverse(input)
|
||||||
ary = [input].flatten
|
ary = InputIterator.new(input)
|
||||||
ary.reverse
|
ary.reverse
|
||||||
end
|
end
|
||||||
|
|
||||||
# map/collect on a given property
|
# map/collect on a given property
|
||||||
def map(input, 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)
|
e = e.call if e.is_a?(Proc)
|
||||||
|
|
||||||
if property == "to_liquid".freeze
|
if property == "to_liquid".freeze
|
||||||
@@ -265,17 +265,6 @@ module Liquid
|
|||||||
|
|
||||||
private
|
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)
|
def to_number(obj)
|
||||||
case obj
|
case obj
|
||||||
when Float
|
when Float
|
||||||
@@ -310,6 +299,36 @@ module Liquid
|
|||||||
result = to_number(input).send(operation, to_number(operand))
|
result = to_number(input).send(operation, to_number(operand))
|
||||||
result.is_a?(BigDecimal) ? result.to_f : result
|
result.is_a?(BigDecimal) ? result.to_f : result
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
Template.register_filter(StandardFilters)
|
Template.register_filter(StandardFilters)
|
||||||
|
|||||||
@@ -67,12 +67,12 @@ class FiltersTest < Test::Unit::TestCase
|
|||||||
@context['value'] = 3
|
@context['value'] = 3
|
||||||
@context['numbers'] = [2,1,4,3]
|
@context['numbers'] = [2,1,4,3]
|
||||||
@context['words'] = ['expected', 'as', 'alphabetic']
|
@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 [1,2,3,4], Variable.new("numbers | sort").render(@context)
|
||||||
assert_equal ['alphabetic', 'as', 'expected'], Variable.new("words | 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 [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
|
end
|
||||||
|
|
||||||
def test_strip_html
|
def test_strip_html
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ class Filters
|
|||||||
end
|
end
|
||||||
|
|
||||||
class TestThing
|
class TestThing
|
||||||
|
attr_reader :foo
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@foo = 0
|
@foo = 0
|
||||||
end
|
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")
|
assert_equal [{"a" => 1}, {"a" => 2}, {"a" => 3}, {"a" => 4}], @filters.sort([{"a" => 4}, {"a" => 3}, {"a" => 1}, {"a" => 2}], "a")
|
||||||
end
|
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
|
def test_numerical_vs_lexicographical_sort
|
||||||
assert_equal [2, 10], @filters.sort([10, 2])
|
assert_equal [2, 10], @filters.sort([10, 2])
|
||||||
assert_equal [{"a" => 2}, {"a" => 10}], @filters.sort([{"a" => 10}, {"a" => 2}], "a")
|
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])
|
assert_equal [4,3,2,1], @filters.reverse([1,2,3,4])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_legacy_reverse_hash
|
||||||
|
assert_equal [{a:1, b:2}], @filters.reverse(a:1, b:2)
|
||||||
|
end
|
||||||
|
|
||||||
def test_map
|
def test_map
|
||||||
assert_equal [1,2,3,4], @filters.map([{"a" => 1}, {"a" => 2}, {"a" => 3}, {"a" => 4}], 'a')
|
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' }}",
|
assert_template_result 'abc', "{{ ary | map:'foo' | map:'bar' }}",
|
||||||
@@ -147,9 +157,16 @@ class StandardFiltersTest < Test::Unit::TestCase
|
|||||||
"thing" => { "foo" => [ { "bar" => 42 }, { "bar" => 17 } ] }
|
"thing" => { "foo" => [ { "bar" => 42 }, { "bar" => 17 } ] }
|
||||||
end
|
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
|
def test_sort_calls_to_liquid
|
||||||
t = TestThing.new
|
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
|
end
|
||||||
|
|
||||||
def test_map_over_proc
|
def test_map_over_proc
|
||||||
|
|||||||
Reference in New Issue
Block a user