Compare commits

...

6 Commits

Author SHA1 Message Date
Arthur Neves
a41a60d294 Bump version to rc1 2013-10-10 10:22:35 -04:00
Florian Weingarten
307cab2eaa History and gemspec
Conflicts:
	History.md
	liquid.gemspec
2013-10-09 17:04:47 -04:00
Arthur Neves
a64360d148 Update history
Conflicts:
	History.md
2013-10-09 16:33:44 -04:00
Florian Weingarten
6cb5a9b7cc Merge pull request #234 from Shopify/fix_mapping_procs
Fix mapping over procs
2013-10-09 16:32:53 -04:00
Florian Weingarten
4207d1f086 Merge pull request #232 from Shopify/to_liquid_stuff
Always call 'to_liquid' on stuff in map filter and allow to_liquid to be...
2013-10-09 16:32:45 -04:00
Florian Weingarten
988a1694fd Use invoke_drop in map filter 2013-10-09 16:32:38 -04:00
6 changed files with 75 additions and 10 deletions

View File

@@ -3,7 +3,7 @@
IMPORTANT: Liquid 2.6 is going to be the last version of Liquid which maintains explicit Ruby 1.8 compatability.
The following releases will only be tested against Ruby 1.9 and Ruby 2.0 and are likely to break on Ruby 1.8.
## 2.6.0 / Master branch (not yet released)
## 2.6.0 (not yet released)
* ...
* Bugfix for #106: fix example servlet [gnowoel]
@@ -24,6 +24,17 @@ The following releases will only be tested against Ruby 1.9 and Ruby 2.0 and are
* Better documentation for 'include' tag (closes #163) [Peter Schröder, phoet]
* Use of BigDecimal on filters to have better precision (closes #155) [Arthur Nogueira Neves, arthurnn]
## 2.5.3 / branch "2.5-stable"
* #232, #234, #237: Fix map filter bugs [Florian Weingarten, fw42]
## 2.5.2 / 2013-09-03 / deleted
Yanked from rubygems, as it contained too many changes that broke compatibility. Those changes will be on following major releases.
## 2.5.1 / 2013-07-24
* #230: Fix security issue with map filter, Use invoke_drop in map filter [Florian Weingarten, fw42]
## 2.5.0 / 2013-03-06

View File

@@ -54,7 +54,7 @@ module Liquid
# Check for method existence without invoking respond_to?, which creates symbols
def self.invokable?(method_name)
@invokable_methods ||= Set.new((public_instance_methods - Liquid::Drop.public_instance_methods).map(&:to_s))
@invokable_methods ||= Set.new(["to_liquid"] + (public_instance_methods - Liquid::Drop.public_instance_methods).map(&:to_s))
@invokable_methods.include?(method_name.to_s)
end
end

View File

@@ -100,10 +100,15 @@ module Liquid
# map/collect on a given property
def map(input, property)
ary = [input].flatten
if ary.first.respond_to?('[]') and !ary.first[property].nil?
ary.map {|e| e[property] }
elsif ary.first.respond_to?(property)
ary.map {|e| e.send(property) }
ary.map do |e|
e = e.call if e.is_a?(Proc)
e = e.to_liquid if e.respond_to?(:to_liquid)
if property == "to_liquid"
e
elsif e.respond_to?(:[])
e[property]
end
end
end

View File

@@ -1,4 +1,4 @@
# encoding: utf-8
module Liquid
VERSION = "2.6.0"
VERSION = "2.6.0.rc1"
end

View File

@@ -71,23 +71,34 @@ class DropsTest < Test::Unit::TestCase
include Liquid
def test_product_drop
assert_nothing_raised do
tpl = Liquid::Template.parse( ' ' )
tpl.render('product' => ProductDrop.new)
end
end
def test_drop_does_only_respond_to_whitelisted_methods
assert_equal "", Liquid::Template.parse("{{ product.inspect }}").render('product' => ProductDrop.new)
assert_equal "", Liquid::Template.parse("{{ product.pretty_inspect }}").render('product' => ProductDrop.new)
assert_equal "", Liquid::Template.parse("{{ product.whatever }}").render('product' => ProductDrop.new)
assert_equal "", Liquid::Template.parse('{{ product | map: "inspect" }}').render('product' => ProductDrop.new)
assert_equal "", Liquid::Template.parse('{{ product | map: "pretty_inspect" }}').render('product' => ProductDrop.new)
assert_equal "", Liquid::Template.parse('{{ product | map: "whatever" }}').render('product' => ProductDrop.new)
end
def test_drops_respond_to_to_liquid
assert_equal "text1", Liquid::Template.parse("{{ product.to_liquid.texts.text }}").render('product' => ProductDrop.new)
assert_equal "text1", Liquid::Template.parse('{{ product | map: "to_liquid" | map: "texts" | map: "text" }}').render('product' => ProductDrop.new)
end
def test_text_drop
output = Liquid::Template.parse( ' {{ product.texts.text }} ' ).render('product' => ProductDrop.new)
assert_equal ' text1 ', output
end
def test_unknown_method
output = Liquid::Template.parse( ' {{ product.catchall.unknown }} ' ).render('product' => ProductDrop.new)
assert_equal ' method: unknown ', output
end
def test_integer_argument_drop

View File

@@ -6,6 +6,27 @@ class Filters
include Liquid::StandardFilters
end
class TestThing
def initialize
@foo = 0
end
def to_s
"woot: #{@foo}"
end
def to_liquid
@foo += 1
self
end
end
class TestDrop < Liquid::Drop
def test
"testfoo"
end
end
class StandardFiltersTest < Test::Unit::TestCase
include Liquid
@@ -97,6 +118,23 @@ class StandardFiltersTest < Test::Unit::TestCase
'ary' => [{'foo' => {'bar' => 'a'}}, {'foo' => {'bar' => 'b'}}, {'foo' => {'bar' => 'c'}}]
end
def test_map_doesnt_call_arbitrary_stuff
assert_equal "", Liquid::Template.parse('{{ "foo" | map: "__id__" }}').render
assert_equal "", Liquid::Template.parse('{{ "foo" | map: "inspect" }}').render
end
def test_map_calls_to_liquid
t = TestThing.new
assert_equal "woot: 1", Liquid::Template.parse('{{ foo }}').render("foo" => t)
end
def test_map_over_proc
drop = TestDrop.new
p = Proc.new{ drop }
templ = '{{ procs | map: "test" }}'
assert_equal "testfoo", Liquid::Template.parse(templ).render("procs" => [p])
end
def test_date
assert_equal 'May', @filters.date(Time.parse("2006-05-05 10:00:00"), "%B")
assert_equal 'June', @filters.date(Time.parse("2006-06-05 10:00:00"), "%B")