diff --git a/lib/jekyll/filters.rb b/lib/jekyll/filters.rb index 79ceed3d..d8915b3a 100644 --- a/lib/jekyll/filters.rb +++ b/lib/jekyll/filters.rb @@ -233,11 +233,11 @@ module Jekyll # # Returns the filtered array of objects def where(input, property, value) - return input unless input.is_a?(Enumerable) + return input unless input.respond_to?(:select) input = input.values if input.is_a?(Hash) input.select do |object| Array(item_property(object, property)).map(&:to_s).include?(value.to_s) - end + end || [] end # Filters an array of objects against an expression @@ -248,7 +248,7 @@ module Jekyll # # Returns the filtered array of objects def where_exp(input, variable, expression) - return input unless input.is_a?(Enumerable) + return input unless input.respond_to?(:select) input = input.values if input.is_a?(Hash) # FIXME condition = parse_condition(expression) @@ -257,7 +257,7 @@ module Jekyll @context[variable] = object condition.evaluate(@context) end - end + end || [] end # Convert the input into integer diff --git a/test/test_filters.rb b/test/test_filters.rb index 7c5ee0b1..1f4a3889 100644 --- a/test/test_filters.rb +++ b/test/test_filters.rb @@ -15,6 +15,10 @@ class TestFilters < JekyllUnitTest end end + class SelectDummy + def select; end + end + context "filters" do setup do @filter = JekyllFilter.new({ @@ -547,6 +551,11 @@ class TestFilters < JekyllUnitTest assert_equal 1, results.length assert_equal 4.7, results[0]["rating"] end + + should "always return an array if the object responds to `select`" do + results = @filter.where(SelectDummy.new, "obj", "1 == 1") + assert_equal [], results + end end context "where_exp filter" do @@ -611,6 +620,19 @@ class TestFilters < JekyllUnitTest assert_equal "b", results[1]["id"] assert_equal "d", results[2]["id"] end + + should "filter posts" do + site = fixture_site.tap(&:read) + posts = site.site_payload["site"]["posts"] + results = @filter.where_exp(posts, "obj", "obj.title == 'Foo Bar'") + assert_equal 1, results.length + assert_equal site.posts.find { |p| p.title == "Foo Bar" }, results.first + end + + should "always return an array if the object responds to `select`" do + results = @filter.where_exp(SelectDummy.new, "obj", "1 == 1") + assert_equal [], results + end end context "sort filter" do