From 2b75bfaff412c23c9b9434a11eafcef869d89c17 Mon Sep 17 00:00:00 2001 From: Ian Ker-Seymer Date: Fri, 4 Apr 2025 11:27:29 -0400 Subject: [PATCH] Fix regression when using empty/nil properties with array filters (#1944) * Make all array filters that use `filter_array` util process empty string and nil correctly * up version * fix ordering of checks * also do it for map * Do not raise property error * Gracefully empty property in map filter --------- Co-authored-by: Marco Concetto Rudilosso --- lib/liquid/standardfilters.rb | 10 ++-- lib/liquid/version.rb | 2 +- test/integration/standard_filter_test.rb | 58 ++++++++++++++++++++++-- 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/lib/liquid/standardfilters.rb b/lib/liquid/standardfilters.rb index 4771b242..4d69f5bc 100644 --- a/lib/liquid/standardfilters.rb +++ b/lib/liquid/standardfilters.rb @@ -3,7 +3,6 @@ require 'cgi' require 'base64' require 'bigdecimal' - module Liquid module StandardFilters MAX_I32 = (1 << 31) - 1 @@ -538,6 +537,10 @@ module Liquid # @liquid_return [array[untyped]] def map(input, property) property = Utils.to_s(property) + + # Return the input array if property is empty (no-op) + return InputIterator.new(input, context).to_a if property.empty? + InputIterator.new(input, context).map do |e| e = e.call if e.is_a?(Proc) @@ -986,12 +989,11 @@ module Liquid attr_reader :context def filter_array(input, property, target_value, default_value = [], &block) - property = Liquid::Utils.to_s(property) - return default_value if property.empty? - ary = InputIterator.new(input, context) return default_value if ary.empty? + property = Utils.to_s(property) + block.call(ary) do |item| if target_value.nil? item[property] diff --git a/lib/liquid/version.rb b/lib/liquid/version.rb index 7d261e99..3f0be7a1 100644 --- a/lib/liquid/version.rb +++ b/lib/liquid/version.rb @@ -2,5 +2,5 @@ # frozen_string_literal: true module Liquid - VERSION = "5.8.2" + VERSION = "5.8.3" end diff --git a/test/integration/standard_filter_test.rb b/test/integration/standard_filter_test.rb index 5c80fe3c..ddf66333 100644 --- a/test/integration/standard_filter_test.rb +++ b/test/integration/standard_filter_test.rb @@ -560,15 +560,47 @@ class StandardFiltersTest < Minitest::Test end end - def test_map_returns_empty_with_no_property - foo = [ + def test_map_with_nil_property + array = [ + { "handle" => "alpha", "value" => "A" }, + { "handle" => "beta", "value" => "B" }, + { "handle" => "gamma", "value" => "C" } + ] + + assert_template_result("alpha beta gamma", "{{ array | map: nil | map: 'handle' | join: ' ' }}", { "array" => array }) + end + + def test_map_with_empty_string_property + array = [ + { "handle" => "alpha", "value" => "A" }, + { "handle" => "beta", "value" => "B" }, + { "handle" => "gamma", "value" => "C" } + ] + + assert_template_result("alpha beta gamma", "{{ array | map: '' | map: 'handle' | join: ' ' }}", { "array" => array }) + end + + def test_map_with_value_property + array = [ + { "handle" => "alpha", "value" => "A" }, + { "handle" => "beta", "value" => "B" }, + { "handle" => "gamma", "value" => "C" } + ] + + assert_template_result("A B C", "{{ array | map: 'value' | join: ' ' }}", { "array" => array }) + end + + def test_map_returns_input_with_no_property + input = [ [1], [2], [3], ] - assert_raises(Liquid::ArgumentError) do - @filters.map(foo, nil) - end + result = @filters.map(input, nil) + assert_equal(input.flatten, result) + + result = @filters.map(input, '') + assert_equal(input.flatten, result) end def test_sort_works_on_enumerables @@ -1033,6 +1065,22 @@ class StandardFiltersTest < Minitest::Test assert_template_result(expected_output, template, { "array" => array }) end + def test_where_with_empty_string_is_a_no_op + environment = { "array" => ["alpha", "beta", "gamma"] } + expected_output = "alpha beta gamma" + template = "{{ array | where: '' | join: ' ' }}" + + assert_template_result(expected_output, template, environment) + end + + def test_where_with_nil_is_a_no_op + environment = { "array" => ["alpha", "beta", "gamma"] } + expected_output = "alpha beta gamma" + template = "{{ array | where: nil | join: ' ' }}" + + assert_template_result(expected_output, template, environment) + end + def test_where_with_value array = [ { "handle" => "alpha", "ok" => true },