diff --git a/History.md b/History.md index db821a1f..eda21408 100644 --- a/History.md +++ b/History.md @@ -2,9 +2,14 @@ ## 5.8.0 (unreleased) +## 5.7.1 2025-01-23 + +* Fix the `find` filter to return `nil` when filtering empty arrays + ## 5.7.0 2025-01-16 ### Features + * Add `find`, `find_index`, `has`, and `reject` filters to arrays * Compatibility with Ruby 3.4 diff --git a/lib/liquid/standardfilters.rb b/lib/liquid/standardfilters.rb index 9da58e06..c4bd8758 100644 --- a/lib/liquid/standardfilters.rb +++ b/lib/liquid/standardfilters.rb @@ -472,7 +472,7 @@ module Liquid # @liquid_syntax array | find: string, string # @liquid_return [untyped] def find(input, property, target_value = nil) - filter_array(input, property, target_value) { |ary, &block| ary.find(&block) } + filter_array(input, property, target_value, nil) { |ary, &block| ary.find(&block) } end # @liquid_public_docs @@ -969,10 +969,10 @@ module Liquid attr_reader :context - def filter_array(input, property, target_value, &block) + def filter_array(input, property, target_value, default_value = [], &block) ary = InputIterator.new(input, context) - return [] if ary.empty? + return default_value if ary.empty? block.call(ary) do |item| if target_value.nil? diff --git a/lib/liquid/version.rb b/lib/liquid/version.rb index 65c0a74f..8cfd6e80 100644 --- a/lib/liquid/version.rb +++ b/lib/liquid/version.rb @@ -2,5 +2,5 @@ # frozen_string_literal: true module Liquid - VERSION = "5.7.0" + VERSION = "5.7.1" end diff --git a/test/integration/standard_filter_test.rb b/test/integration/standard_filter_test.rb index ce2a2841..3ea9abae 100644 --- a/test/integration/standard_filter_test.rb +++ b/test/integration/standard_filter_test.rb @@ -157,6 +157,10 @@ class StandardFiltersTest < Minitest::Test assert_equal([], @filters.slice(input, -(1 << 63), 6)) end + def test_find_on_empty_array + assert_nil(@filters.find([], 'foo', 'bar')) + end + def test_truncate assert_equal('1234...', @filters.truncate('1234567890', 7)) assert_equal('1234567890', @filters.truncate('1234567890', 20)) @@ -1042,6 +1046,18 @@ class StandardFiltersTest < Minitest::Test assert_template_result(expected_output, template, { "products" => TestDeepEnumerable.new }) end + def test_find_with_empty_arrays + template = <<~LIQUID + {%- assign product = products | find: 'title.content', 'Not found' -%} + {%- unless product -%} + Product not found. + {%- endunless -%} + LIQUID + expected_output = "Product not found." + + assert_template_result(expected_output, template, { "products" => [] }) + end + def test_find_index_with_value products = [ { "title" => "Pro goggles", "price" => 1299 },