mirror of
https://github.com/Shopify/liquid.git
synced 2026-09-15 00:40:40 -07:00
Update branch with main
This commit is contained in:
-11
@@ -1,6 +1,5 @@
|
||||
# Liquid Change Log
|
||||
|
||||
<<<<<<< HEAD
|
||||
## 5.5.0 2024-03-21
|
||||
|
||||
Please reference the GitHub release for more information.
|
||||
@@ -14,7 +13,6 @@ Please reference the GitHub release for more information.
|
||||
* Allow `#` to be used as an inline comment tag (#1498) [CP Clermont]
|
||||
|
||||
### Fixes
|
||||
<<<<<<< HEAD
|
||||
* `PartialCache` now shares snippet cache with subcontexts by default (#1553) [Chris AtLee]
|
||||
* Hash registers no longer leak into subcontexts as static registers (#1564) [Chris AtLee]
|
||||
* Fix `ParseTreeVisitor` for `with` variable expressions in `Render` tag (#1596) [CP Clermont]
|
||||
@@ -36,19 +34,10 @@ Please reference the GitHub release for more information.
|
||||
### Features
|
||||
* Add `remove_last`, and `replace_last` filters (#1422) [Anders Hagbard]
|
||||
* Eagerly cache global filters (#1524) [Jean Boussier]
|
||||
=======
|
||||
## 5.2.0 (unreleased)
|
||||
|
||||
### Features
|
||||
* Add `remove_last`, and `replace_last` filters (#1422) [Anders Hagbard]
|
||||
>>>>>>> 588d407e (Fix new changelog entry so it is under unreleased)
|
||||
|
||||
### Fixes
|
||||
* Fix some internal errors in filters from invalid input (#1476) [Dylan Thacker-Smith]
|
||||
* Allow dash in filter kwarg name for consistency with Liquid::C (#1518) [CP Clermont]
|
||||
=======
|
||||
* Fix some internal errors in filters from invalid input (#1476) [Dylan Thacker-Smith]
|
||||
>>>>>>> 50c88fe7 (History.md: Add missing PR number to previous changelog entry)
|
||||
|
||||
## 5.1.0 / 2021-09-09
|
||||
|
||||
|
||||
+18
-144
@@ -367,10 +367,7 @@ module Liquid
|
||||
# Sorts the items in an array in case-sensitive alphabetical, or numerical, order.
|
||||
# @liquid_syntax array | sort
|
||||
# @liquid_return [array[untyped]]
|
||||
# @liquid_optional_param deep [boolean | string] Whether to use dot notation to perform a deep search. A string can be passed to change separator.
|
||||
def sort(input, property = nil, options = {})
|
||||
options = {} unless options.is_a?(Hash)
|
||||
deep = deep_search_properties(property, options)
|
||||
def sort(input, property = nil)
|
||||
ary = InputIterator.new(input, context)
|
||||
|
||||
return [] if ary.empty?
|
||||
@@ -381,13 +378,7 @@ module Liquid
|
||||
end
|
||||
elsif ary.all? { |el| el.respond_to?(:[]) }
|
||||
begin
|
||||
ary.sort do |a, b|
|
||||
if deep[:enable]
|
||||
nil_safe_compare(a.dig(*deep[:properties]), b.dig(*deep[:properties]))
|
||||
else
|
||||
nil_safe_compare(a[property], b[property])
|
||||
end
|
||||
end
|
||||
ary.sort { |a, b| nil_safe_compare(a[property], b[property]) }
|
||||
rescue TypeError
|
||||
raise_property_error(property)
|
||||
end
|
||||
@@ -405,10 +396,7 @@ module Liquid
|
||||
# > string, so sorting on numerical values can lead to unexpected results.
|
||||
# @liquid_syntax array | sort_natural
|
||||
# @liquid_return [array[untyped]]
|
||||
# @liquid_optional_param deep [boolean | string] Whether to use dot notation to perform a deep search. A string can be passed to change separator.
|
||||
def sort_natural(input, property = nil, options = {})
|
||||
options = {} unless options.is_a?(Hash)
|
||||
deep = deep_search_properties(property, options)
|
||||
def sort_natural(input, property = nil)
|
||||
ary = InputIterator.new(input, context)
|
||||
|
||||
return [] if ary.empty?
|
||||
@@ -419,13 +407,7 @@ module Liquid
|
||||
end
|
||||
elsif ary.all? { |el| el.respond_to?(:[]) }
|
||||
begin
|
||||
ary.sort do |a, b|
|
||||
if deep[:enable]
|
||||
nil_safe_casecmp(a.dig(*deep[:properties]), b.dig(*deep[:properties]))
|
||||
else
|
||||
nil_safe_casecmp(a[property], b[property])
|
||||
end
|
||||
end
|
||||
ary.sort { |a, b| nil_safe_casecmp(a[property], b[property]) }
|
||||
rescue TypeError
|
||||
raise_property_error(property)
|
||||
end
|
||||
@@ -441,10 +423,7 @@ module Liquid
|
||||
# This requires you to provide both the property name and the associated value.
|
||||
# @liquid_syntax array | where: string, string
|
||||
# @liquid_return [array[untyped]]
|
||||
# @liquid_optional_param deep [boolean | string] Whether to use dot notation to perform a deep search. A string can be passed to change separator.
|
||||
def where(input, property, target_value = nil, options = {})
|
||||
options = {} unless options.is_a?(Hash)
|
||||
deep = deep_search_properties(property, options)
|
||||
def where(input, property, target_value = nil)
|
||||
ary = InputIterator.new(input, context)
|
||||
|
||||
if ary.empty?
|
||||
@@ -460,8 +439,7 @@ module Liquid
|
||||
end
|
||||
else
|
||||
ary.select do |item|
|
||||
item_value = deep[:enable] ? item.dig(*deep[:properties]) : item[property]
|
||||
item_value == target_value
|
||||
item[property] == target_value
|
||||
rescue TypeError
|
||||
raise_property_error(property)
|
||||
rescue NoMethodError
|
||||
@@ -471,7 +449,6 @@ module Liquid
|
||||
end
|
||||
end
|
||||
|
||||
<<<<<<< HEAD
|
||||
# @liquid_public_docs
|
||||
# @liquid_type filter
|
||||
# @liquid_category array
|
||||
@@ -479,41 +456,7 @@ module Liquid
|
||||
# Removes any duplicate items in an array.
|
||||
# @liquid_syntax array | uniq
|
||||
# @liquid_return [array[untyped]]
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
# Reject the elements of an array to those with a certain property value.
|
||||
# By default the target is any falsy value.
|
||||
def reject(input, properties, target_value = nil)
|
||||
raise_property_error(properties) unless properties.is_a?(String)
|
||||
|
||||
properties = properties.to_s.split('.')
|
||||
ary = InputIterator.new(input, context)
|
||||
|
||||
ary.reject do |item|
|
||||
if item.is_a?(Hash)
|
||||
value = item.dig(*properties)
|
||||
|
||||
if target_value.nil?
|
||||
!value
|
||||
else
|
||||
value == target_value
|
||||
end
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Remove duplicate elements from an array
|
||||
# provide optional property with which to determine uniqueness
|
||||
>>>>>>> bfdcfcea (Add reject filter)
|
||||
def uniq(input, property = nil)
|
||||
=======
|
||||
# @liquid_optional_param deep [boolean | string] Whether to use dot notation to perform a deep search. A string can be passed to change separator.
|
||||
def uniq(input, property = nil, options = {})
|
||||
options = {} unless options.is_a?(Hash)
|
||||
deep = deep_search_properties(property, options)
|
||||
>>>>>>> 58d7d1a8 (Add deep search for suitable filters)
|
||||
ary = InputIterator.new(input, context)
|
||||
|
||||
if property.nil?
|
||||
@@ -522,7 +465,7 @@ module Liquid
|
||||
[]
|
||||
else
|
||||
ary.uniq do |item|
|
||||
deep[:enable] ? item.dig(*deep[:properties]) : item[property]
|
||||
item[property]
|
||||
rescue TypeError
|
||||
raise_property_error(property)
|
||||
rescue NoMethodError
|
||||
@@ -551,19 +494,15 @@ module Liquid
|
||||
# Creates an array of values from a specific property of the items in an array.
|
||||
# @liquid_syntax array | map: string
|
||||
# @liquid_return [array[untyped]]
|
||||
# @liquid_optional_param deep [boolean | string] Whether to use dot notation to perform a deep search. A string can be passed to change separator.
|
||||
def map(input, property, options = {})
|
||||
options = {} unless options.is_a?(Hash)
|
||||
deep = deep_search_properties(property, options)
|
||||
|
||||
InputIterator.new(input, context).map do |item|
|
||||
item = item.call if item.is_a?(Proc)
|
||||
def map(input, property)
|
||||
InputIterator.new(input, context).map do |e|
|
||||
e = e.call if e.is_a?(Proc)
|
||||
|
||||
if property == "to_liquid"
|
||||
item
|
||||
elsif item.respond_to?(:[])
|
||||
result = deep[:enable] ? item.dig(*deep[:properties]) : item[property]
|
||||
result.is_a?(Proc) ? result.call : result
|
||||
e
|
||||
elsif e.respond_to?(:[])
|
||||
r = e[property]
|
||||
r.is_a?(Proc) ? r.call : r
|
||||
end
|
||||
end
|
||||
rescue TypeError
|
||||
@@ -577,10 +516,7 @@ module Liquid
|
||||
# Removes any `nil` items from an array.
|
||||
# @liquid_syntax array | compact
|
||||
# @liquid_return [array[untyped]]
|
||||
# @liquid_optional_param deep [boolean | string] Whether to use dot notation to perform a deep search. A string can be passed to change separator.
|
||||
def compact(input, property = nil, options = {})
|
||||
options = {} unless options.is_a?(Hash)
|
||||
deep = deep_search_properties(property, options)
|
||||
def compact(input, property = nil)
|
||||
ary = InputIterator.new(input, context)
|
||||
|
||||
if property.nil?
|
||||
@@ -589,7 +525,7 @@ module Liquid
|
||||
[]
|
||||
else
|
||||
ary.reject do |item|
|
||||
deep[:enable] ? item.dig(*deep[:properties]).nil? : item[property].nil?
|
||||
item[property].nil?
|
||||
rescue TypeError
|
||||
raise_property_error(property)
|
||||
rescue NoMethodError
|
||||
@@ -621,7 +557,6 @@ module Liquid
|
||||
input.to_s.sub(string.to_s, replacement.to_s)
|
||||
end
|
||||
|
||||
<<<<<<< HEAD
|
||||
# @liquid_public_docs
|
||||
# @liquid_type filter
|
||||
# @liquid_category string
|
||||
@@ -650,34 +585,8 @@ module Liquid
|
||||
# Removes any instance of a substring inside a string.
|
||||
# @liquid_syntax string | remove: string
|
||||
# @liquid_return [string]
|
||||
=======
|
||||
# Replace the last occurrences of a string with another
|
||||
def replace_last(input, string, replacement)
|
||||
input = input.to_s
|
||||
string = string.to_s
|
||||
replacement = replacement.to_s
|
||||
|
||||
start_index = input.rindex(string)
|
||||
|
||||
return input unless start_index
|
||||
|
||||
output = input.dup
|
||||
output[start_index, string.length] = replacement
|
||||
output
|
||||
end
|
||||
|
||||
# remove a substring
|
||||
>>>>>>> e575c1f1 (Add replace_last and remove_last filters)
|
||||
def remove(input, string)
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
replace(input, string, '')
|
||||
=======
|
||||
replace(input.to_s, string, '')
|
||||
>>>>>>> f72cfb13 (Delegate functions to corresponding replace functions)
|
||||
=======
|
||||
replace(input, string, '')
|
||||
>>>>>>> 5187399f (Update lib/liquid/standardfilters.rb)
|
||||
end
|
||||
|
||||
# @liquid_public_docs
|
||||
@@ -688,18 +597,9 @@ module Liquid
|
||||
# @liquid_syntax string | remove_first: string
|
||||
# @liquid_return [string]
|
||||
def remove_first(input, string)
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
replace_first(input, string, '')
|
||||
=======
|
||||
replace_first(input.to_s, string, '')
|
||||
>>>>>>> f72cfb13 (Delegate functions to corresponding replace functions)
|
||||
=======
|
||||
replace_first(input, string, '')
|
||||
>>>>>>> 45f186b4 (Remove string formatter)
|
||||
end
|
||||
|
||||
<<<<<<< HEAD
|
||||
# @liquid_public_docs
|
||||
# @liquid_type filter
|
||||
# @liquid_category string
|
||||
@@ -718,14 +618,6 @@ module Liquid
|
||||
# Adds a given string to the end of a string.
|
||||
# @liquid_syntax string | append: string
|
||||
# @liquid_return [string]
|
||||
=======
|
||||
# remove the last occurences of a substring
|
||||
def remove_last(input, string)
|
||||
replace_last(input, string, '')
|
||||
end
|
||||
|
||||
# add one string to another
|
||||
>>>>>>> e575c1f1 (Add replace_last and remove_last filters)
|
||||
def append(input, string)
|
||||
input.to_s + string.to_s
|
||||
end
|
||||
@@ -999,11 +891,7 @@ module Liquid
|
||||
# Returns the sum of all elements in an array.
|
||||
# @liquid_syntax array | sum
|
||||
# @liquid_return [number]
|
||||
# @liquid_optional_param deep [boolean | string] Whether to use dot notation to perform a deep search. A string can be passed to change separator.
|
||||
def sum(input, property = nil, options = {})
|
||||
options = {} unless options.is_a?(Hash)
|
||||
deep = deep_search_properties(property, options)
|
||||
|
||||
def sum(input, property = nil)
|
||||
ary = InputIterator.new(input, context)
|
||||
return 0 if ary.empty?
|
||||
|
||||
@@ -1011,7 +899,7 @@ module Liquid
|
||||
if property.nil?
|
||||
item
|
||||
elsif item.respond_to?(:[])
|
||||
deep[:enable] ? item.dig(*deep[:properties]) : item[property]
|
||||
item[property]
|
||||
else
|
||||
0
|
||||
end
|
||||
@@ -1063,20 +951,6 @@ module Liquid
|
||||
end
|
||||
end
|
||||
|
||||
def deep_search_properties(key, options = {})
|
||||
options = {} unless options.is_a?(Hash)
|
||||
|
||||
enable = options['deep'] ? true : false
|
||||
separator = options['deep'].is_a?(String) ? options['deep'] : '.' if enable
|
||||
properties = key.to_s.split(separator) if enable
|
||||
|
||||
{
|
||||
enable: enable,
|
||||
separator: separator,
|
||||
properties: properties,
|
||||
}
|
||||
end
|
||||
|
||||
class InputIterator
|
||||
include Enumerable
|
||||
|
||||
|
||||
@@ -286,60 +286,6 @@ class StandardFiltersTest < Minitest::Test
|
||||
assert_equal([{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }], @filters.sort([{ "a" => 4 }, { "a" => 3 }, { "a" => 1 }, { "a" => 2 }], "a"))
|
||||
end
|
||||
|
||||
def test_sort_deep_default_separator
|
||||
input = [
|
||||
{ "foo" => { "price" => 4, "handle" => "alpha" } },
|
||||
{ "foo" => { "handle" => "beta" } },
|
||||
{ "foo" => { "price" => 1, "handle" => "gamma" } },
|
||||
{ "foo" => { "handle" => "delta" } },
|
||||
{ "foo" => { "price" => 2, "handle" => "epsilon" } },
|
||||
]
|
||||
expectation = [
|
||||
{ "foo" => { "price" => 1, "handle" => "gamma" } },
|
||||
{ "foo" => { "price" => 2, "handle" => "epsilon" } },
|
||||
{ "foo" => { "price" => 4, "handle" => "alpha" } },
|
||||
{ "foo" => { "handle" => "beta" } },
|
||||
{ "foo" => { "handle" => "delta" } },
|
||||
]
|
||||
assert_equal(expectation, @filters.sort(input, "foo.price", { "deep" => true }))
|
||||
end
|
||||
|
||||
def test_sort_deep_custom_separator
|
||||
input = [
|
||||
{ "foo" => { "price" => 4, "handle" => "alpha" } },
|
||||
{ "foo" => { "handle" => "beta" } },
|
||||
{ "foo" => { "price" => 1, "handle" => "gamma" } },
|
||||
{ "foo" => { "handle" => "delta" } },
|
||||
{ "foo" => { "price" => 2, "handle" => "epsilon" } },
|
||||
]
|
||||
expectation = [
|
||||
{ "foo" => { "price" => 1, "handle" => "gamma" } },
|
||||
{ "foo" => { "price" => 2, "handle" => "epsilon" } },
|
||||
{ "foo" => { "price" => 4, "handle" => "alpha" } },
|
||||
{ "foo" => { "handle" => "beta" } },
|
||||
{ "foo" => { "handle" => "delta" } },
|
||||
]
|
||||
assert_equal(expectation, @filters.sort(input, "foo_price", { "deep" => "_" }))
|
||||
end
|
||||
|
||||
def test_sort_deep_off_by_default
|
||||
input = [
|
||||
{ "foo.price" => 4, "handle" => "alpha" },
|
||||
{ "handle" => "beta" },
|
||||
{ "foo.price" => 1, "handle" => "gamma" },
|
||||
{ "handle" => "delta" },
|
||||
{ "foo.price" => 2, "handle" => "epsilon" },
|
||||
]
|
||||
expectation = [
|
||||
{ "foo.price" => 1, "handle" => "gamma" },
|
||||
{ "foo.price" => 2, "handle" => "epsilon" },
|
||||
{ "foo.price" => 4, "handle" => "alpha" },
|
||||
{ "handle" => "beta" },
|
||||
{ "handle" => "delta" },
|
||||
]
|
||||
assert_equal(expectation, @filters.sort(input, "foo.price"))
|
||||
end
|
||||
|
||||
def test_sort_with_nils
|
||||
assert_equal([1, 2, 3, 4, nil], @filters.sort([nil, 4, 3, 2, 1]))
|
||||
assert_equal([{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }, {}], @filters.sort([{ "a" => 4 }, { "a" => 3 }, {}, { "a" => 1 }, { "a" => 2 }], "a"))
|
||||
@@ -414,72 +360,6 @@ class StandardFiltersTest < Minitest::Test
|
||||
assert_equal(["a", "b", "c", "X", "Y", "Z"], @filters.sort_natural(["X", "Y", "Z", "a", "b", "c"]))
|
||||
end
|
||||
|
||||
def test_sort_natural_deep_default_separator
|
||||
input = [
|
||||
{ "foo" => { "key" => "X" } },
|
||||
{ "foo" => { "key" => "Y" } },
|
||||
{ "foo" => { "key" => "Z" } },
|
||||
{ "foo" => { "fake" => "t" } },
|
||||
{ "foo" => { "key" => "a" } },
|
||||
{ "foo" => { "key" => "b" } },
|
||||
{ "foo" => { "key" => "c" } },
|
||||
]
|
||||
expectation = [
|
||||
{ "foo" => { "key" => "a" } },
|
||||
{ "foo" => { "key" => "b" } },
|
||||
{ "foo" => { "key" => "c" } },
|
||||
{ "foo" => { "key" => "X" } },
|
||||
{ "foo" => { "key" => "Y" } },
|
||||
{ "foo" => { "key" => "Z" } },
|
||||
{ "foo" => { "fake" => "t" } },
|
||||
]
|
||||
assert_equal(expectation, @filters.sort_natural(input, "foo.key", { "deep" => true }))
|
||||
end
|
||||
|
||||
def test_sort_natural_deep_custom_separator
|
||||
input = [
|
||||
{ "foo" => { "key" => "X" } },
|
||||
{ "foo" => { "key" => "Y" } },
|
||||
{ "foo" => { "key" => "Z" } },
|
||||
{ "foo" => { "fake" => "t" } },
|
||||
{ "foo" => { "key" => "a" } },
|
||||
{ "foo" => { "key" => "b" } },
|
||||
{ "foo" => { "key" => "c" } },
|
||||
]
|
||||
expectation = [
|
||||
{ "foo" => { "key" => "a" } },
|
||||
{ "foo" => { "key" => "b" } },
|
||||
{ "foo" => { "key" => "c" } },
|
||||
{ "foo" => { "key" => "X" } },
|
||||
{ "foo" => { "key" => "Y" } },
|
||||
{ "foo" => { "key" => "Z" } },
|
||||
{ "foo" => { "fake" => "t" } },
|
||||
]
|
||||
assert_equal(expectation, @filters.sort_natural(input, "foo_key", { "deep" => "_" }))
|
||||
end
|
||||
|
||||
def test_sort_natural_deep_off_by_default
|
||||
input = [
|
||||
{ "foo.key" => "X" },
|
||||
{ "foo.key" => "Y" },
|
||||
{ "foo.key" => "Z" },
|
||||
{ "foo.fake" => "t" },
|
||||
{ "foo.key" => "a" },
|
||||
{ "foo.key" => "b" },
|
||||
{ "foo.key" => "c" },
|
||||
]
|
||||
expectation = [
|
||||
{ "foo.key" => "a" },
|
||||
{ "foo.key" => "b" },
|
||||
{ "foo.key" => "c" },
|
||||
{ "foo.key" => "X" },
|
||||
{ "foo.key" => "Y" },
|
||||
{ "foo.key" => "Z" },
|
||||
{ "foo.fake" => "t" },
|
||||
]
|
||||
assert_equal(expectation, @filters.sort_natural(input, "foo.key"))
|
||||
end
|
||||
|
||||
def test_sort_empty_array
|
||||
assert_equal([], @filters.sort([], "a"))
|
||||
end
|
||||
@@ -548,45 +428,6 @@ class StandardFiltersTest < Minitest::Test
|
||||
end
|
||||
end
|
||||
|
||||
def test_uniq_deep_default_separator
|
||||
input = [
|
||||
{ "foo" => { "bar" => "baz", "handle" => "alpha" } },
|
||||
{ "foo" => { "bar" => "baz", "handle" => "beta" } },
|
||||
{ "foo" => { "bar" => "qux", "handle" => "charlie" } },
|
||||
]
|
||||
expectation = [
|
||||
{ "foo" => { "bar" => "baz", "handle" => "alpha" } },
|
||||
{ "foo" => { "bar" => "qux", "handle" => "charlie" } },
|
||||
]
|
||||
assert_equal(expectation, @filters.uniq(input, "foo.bar", { "deep" => true }))
|
||||
end
|
||||
|
||||
def test_uniq_deep_custom_separator
|
||||
input = [
|
||||
{ "foo" => { "bar" => "baz", "handle" => "alpha" } },
|
||||
{ "foo" => { "bar" => "baz", "handle" => "beta" } },
|
||||
{ "foo" => { "bar" => "qux", "handle" => "charlie" } },
|
||||
]
|
||||
expectation = [
|
||||
{ "foo" => { "bar" => "baz", "handle" => "alpha" } },
|
||||
{ "foo" => { "bar" => "qux", "handle" => "charlie" } },
|
||||
]
|
||||
assert_equal(expectation, @filters.uniq(input, "foo_bar", { "deep" => "_" }))
|
||||
end
|
||||
|
||||
def test_uniq_deep_off_by_default
|
||||
input = [
|
||||
{ "foo.bar" => "baz", "handle" => "alpha" },
|
||||
{ "foo.bar" => "baz", "handle" => "beta" },
|
||||
{ "foo.bar" => "qux", "handle" => "charlie" },
|
||||
]
|
||||
expectation = [
|
||||
{ "foo.bar" => "baz", "handle" => "alpha" },
|
||||
{ "foo.bar" => "qux", "handle" => "charlie" },
|
||||
]
|
||||
assert_equal(expectation, @filters.uniq(input, "foo.bar"))
|
||||
end
|
||||
|
||||
def test_compact_empty_array
|
||||
assert_equal([], @filters.compact([], "a"))
|
||||
end
|
||||
@@ -603,45 +444,6 @@ class StandardFiltersTest < Minitest::Test
|
||||
end
|
||||
end
|
||||
|
||||
def test_compact_deep_default_separator
|
||||
input = [
|
||||
{ "foo" => { "bar" => "baz", "handle" => "alpha" } },
|
||||
{ "foo" => { "handle" => "beta" } },
|
||||
{ "foo" => { "bar" => "qux", "handle" => "charlie" } },
|
||||
]
|
||||
expectation = [
|
||||
{ "foo" => { "bar" => "baz", "handle" => "alpha" } },
|
||||
{ "foo" => { "bar" => "qux", "handle" => "charlie" } },
|
||||
]
|
||||
assert_equal(expectation, @filters.compact(input, "foo.bar", { "deep" => true }))
|
||||
end
|
||||
|
||||
def test_compact_deep_custom_separator
|
||||
input = [
|
||||
{ "foo" => { "bar" => "baz", "handle" => "alpha" } },
|
||||
{ "foo" => { "handle" => "beta" } },
|
||||
{ "foo" => { "bar" => "qux", "handle" => "charlie" } },
|
||||
]
|
||||
expectation = [
|
||||
{ "foo" => { "bar" => "baz", "handle" => "alpha" } },
|
||||
{ "foo" => { "bar" => "qux", "handle" => "charlie" } },
|
||||
]
|
||||
assert_equal(expectation, @filters.compact(input, "foo_bar", { "deep" => "_" }))
|
||||
end
|
||||
|
||||
def test_compact_deep_off_by_default
|
||||
input = [
|
||||
{ "foo.bar" => "baz", "handle" => "alpha" },
|
||||
{ "foo.handle" => "beta" },
|
||||
{ "foo.bar" => "qux", "handle" => "charlie" },
|
||||
]
|
||||
expectation = [
|
||||
{ "foo.bar" => "baz", "handle" => "alpha" },
|
||||
{ "foo.bar" => "qux", "handle" => "charlie" },
|
||||
]
|
||||
assert_equal(expectation, @filters.compact(input, "foo.bar"))
|
||||
end
|
||||
|
||||
def test_reverse
|
||||
assert_equal([4, 3, 2, 1], @filters.reverse([1, 2, 3, 4]))
|
||||
end
|
||||
@@ -659,30 +461,6 @@ class StandardFiltersTest < Minitest::Test
|
||||
)
|
||||
end
|
||||
|
||||
def test_map_deep_default_separator
|
||||
assert_template_result(
|
||||
'abc',
|
||||
"{{ ary | map: 'foo.bar', deep: true }}",
|
||||
{ 'ary' => [{ 'foo' => { 'bar' => 'a' } }, { 'foo' => { 'bar' => 'b' } }, { 'foo' => { 'bar' => 'c' } }] },
|
||||
)
|
||||
end
|
||||
|
||||
def test_map_deep_custom_separator
|
||||
assert_template_result(
|
||||
'abc',
|
||||
"{{ ary | map: 'foo_bar', deep: '_' }}",
|
||||
{ 'ary' => [{ 'foo' => { 'bar' => 'a' } }, { 'foo' => { 'bar' => 'b' } }, { 'foo' => { 'bar' => 'c' } }] },
|
||||
)
|
||||
end
|
||||
|
||||
def test_map_deep_off_by_default
|
||||
assert_template_result(
|
||||
'abc',
|
||||
"{{ ary | map: 'foo.bar' }}",
|
||||
{ 'ary' => [{ 'foo.bar' => 'a' }, { 'foo.bar' => 'b' }, { 'foo.bar' => 'c' }] },
|
||||
)
|
||||
end
|
||||
|
||||
def test_map_doesnt_call_arbitrary_stuff
|
||||
assert_template_result("", '{{ "foo" | map: "__id__" }}')
|
||||
assert_template_result("", '{{ "foo" | map: "inspect" }}')
|
||||
@@ -825,38 +603,9 @@ class StandardFiltersTest < Minitest::Test
|
||||
def test_replace
|
||||
assert_equal('b b b b', @filters.replace('a a a a', 'a', 'b'))
|
||||
assert_equal('2 2 2 2', @filters.replace('1 1 1 1', 1, 2))
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
assert_equal('1 1 1 1', @filters.replace('1 1 1 1', 2, 3))
|
||||
assert_template_result('2 2 2 2', "{{ '1 1 1 1' | replace: '1', 2 }}")
|
||||
|
||||
<<<<<<< HEAD
|
||||
assert_equal('b a a a', @filters.replace_first('a a a a', 'a', 'b'))
|
||||
=======
|
||||
>>>>>>> 38b7364f (Improve tests)
|
||||
assert_equal('2 1 1 1', @filters.replace_first('1 1 1 1', 1, 2))
|
||||
assert_equal('1 1 1 1', @filters.replace_first('1 1 1 1', 2, 3))
|
||||
assert_template_result('2 1 1 1', "{{ '1 1 1 1' | replace_first: '1', 2 }}")
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
|
||||
assert_equal('a a a b', @filters.replace_last('a a a a', 'a', 'b'))
|
||||
assert_equal('1 1 1 2', @filters.replace_last('1 1 1 1', 1, 2))
|
||||
assert_equal('1 1 1 1', @filters.replace_last('1 1 1 1', 2, 3))
|
||||
=======
|
||||
assert_equal('1 1 1 2', @filters.replace_last('1 1 1 1', '1', 2))
|
||||
=======
|
||||
>>>>>>> 38b7364f (Improve tests)
|
||||
assert_equal('1 1 1 2', @filters.replace_last('1 1 1 1', 1, 2))
|
||||
>>>>>>> 832516fb (Add replace_last and remove_last tests)
|
||||
assert_template_result('1 1 1 2', "{{ '1 1 1 1' | replace_last: '1', 2 }}")
|
||||
=======
|
||||
=======
|
||||
assert_equal('1 1 1 1', @filters.replace('1 1 1 1', 2, 3))
|
||||
>>>>>>> d81f7f04 (Add tests to make sure it returns original string on no replacement)
|
||||
=======
|
||||
>>>>>>> 63ae4cc2 (Remove redundant test assertions)
|
||||
assert_equal('b a a a', @filters.replace_first('a a a a', 'a', 'b'))
|
||||
assert_equal('2 1 1 1', @filters.replace_first('1 1 1 1', 1, 2))
|
||||
assert_equal('1 1 1 1', @filters.replace_first('1 1 1 1', 2, 3))
|
||||
@@ -865,29 +614,11 @@ class StandardFiltersTest < Minitest::Test
|
||||
assert_equal('a a a b', @filters.replace_last('a a a a', 'a', 'b'))
|
||||
assert_equal('1 1 1 2', @filters.replace_last('1 1 1 1', 1, 2))
|
||||
assert_equal('1 1 1 1', @filters.replace_last('1 1 1 1', 2, 3))
|
||||
<<<<<<< HEAD
|
||||
assert_template_result('b b b b', "{{ 'a a a a' | replace: 'a', 'b' }}")
|
||||
assert_template_result('2 2 2 2', "{{ '1 1 1 1' | replace: 1, 2 }}")
|
||||
assert_template_result('1 1 1 1', "{{ '1 1 1 1' | replace: 2, 3 }}")
|
||||
assert_template_result('b a a a', "{{ 'a a a a' | replace_first: 'a', 'b' }}")
|
||||
assert_template_result('2 1 1 1', "{{ '1 1 1 1' | replace_first: 1, 2 }}")
|
||||
assert_template_result('a a a a', "{{ 'a a a a' | replace_first: 'b', 'c' }}")
|
||||
assert_template_result('a a a b', "{{ 'a a a a' | replace_last: 'a', 'b' }}")
|
||||
assert_template_result('1 1 1 2', "{{ '1 1 1 1' | replace_last: 1, 2 }}")
|
||||
<<<<<<< HEAD
|
||||
>>>>>>> b3d14e5b (Update tests)
|
||||
=======
|
||||
assert_template_result('a a a a', "{{ 'a a a a' | replace_last: 'b', 'c' }}")
|
||||
>>>>>>> d81f7f04 (Add tests to make sure it returns original string on no replacement)
|
||||
=======
|
||||
assert_template_result('1 1 1 2', "{{ '1 1 1 1' | replace_last: '1', 2 }}")
|
||||
>>>>>>> 63ae4cc2 (Remove redundant test assertions)
|
||||
end
|
||||
|
||||
def test_remove
|
||||
assert_equal(' ', @filters.remove("a a a a", 'a'))
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
assert_template_result(' ', "{{ '1 1 1 1' | remove: 1 }}")
|
||||
|
||||
assert_equal('b a a', @filters.remove_first("a b a a", 'a '))
|
||||
@@ -895,31 +626,6 @@ class StandardFiltersTest < Minitest::Test
|
||||
|
||||
assert_equal('a a b', @filters.remove_last("a a b a", ' a'))
|
||||
assert_template_result('1 1 1 ', "{{ '1 1 1 1' | remove_last: 1 }}")
|
||||
=======
|
||||
assert_equal(' ', @filters.remove("1 1 1 1", 1))
|
||||
assert_equal('b a a', @filters.remove_first("a b a a", 'a '))
|
||||
assert_equal(' 1 1 1', @filters.remove_first("1 1 1 1", 1))
|
||||
assert_equal('a a b', @filters.remove_last("a a b a", ' a'))
|
||||
assert_equal('1 1 1 ', @filters.remove_last("1 1 1 1", 1))
|
||||
<<<<<<< HEAD
|
||||
<<<<<<< HEAD
|
||||
assert_template_result('a a a', "{{ 'a a a a' | remove_last: ' a' }}")
|
||||
>>>>>>> 832516fb (Add replace_last and remove_last tests)
|
||||
=======
|
||||
assert_template_result('a a b', "{{ 'a a b a' | remove_last: ' a' }}")
|
||||
>>>>>>> effee1ed (Update tests)
|
||||
=======
|
||||
assert_template_result(' ', "{{ 'a a a a' | remove: 'a' }}")
|
||||
=======
|
||||
>>>>>>> 63ae4cc2 (Remove redundant test assertions)
|
||||
assert_template_result(' ', "{{ '1 1 1 1' | remove: 1 }}")
|
||||
|
||||
assert_equal('b a a', @filters.remove_first("a b a a", 'a '))
|
||||
assert_template_result(' 1 1 1', "{{ '1 1 1 1' | remove_first: 1 }}")
|
||||
|
||||
assert_equal('a a b', @filters.remove_last("a a b a", ' a'))
|
||||
assert_template_result('1 1 1 ', "{{ '1 1 1 1' | remove_last: 1 }}")
|
||||
>>>>>>> b3d14e5b (Update tests)
|
||||
end
|
||||
|
||||
def test_pipes_in_string_arguments
|
||||
@@ -1194,121 +900,6 @@ class StandardFiltersTest < Minitest::Test
|
||||
assert_nil(@filters.where([nil], "ok"))
|
||||
end
|
||||
|
||||
<<<<<<< HEAD
|
||||
def test_reject
|
||||
input = [
|
||||
{ "handle" => "alpha", "ok" => true },
|
||||
{ "handle" => "beta", "ok" => false },
|
||||
{ "handle" => "gamma", "ok" => false },
|
||||
{ "handle" => "delta", "ok" => true },
|
||||
]
|
||||
|
||||
expectation = [
|
||||
{ "handle" => "alpha", "ok" => true },
|
||||
{ "handle" => "delta", "ok" => true },
|
||||
]
|
||||
|
||||
assert_equal(expectation, @filters.reject(input, "ok", false))
|
||||
assert_equal(expectation, @filters.reject(input, "ok"))
|
||||
end
|
||||
|
||||
def test_reject_no_key_set
|
||||
input = [
|
||||
{ "handle" => "alpha", "ok" => true },
|
||||
{ "handle" => "beta" },
|
||||
{ "handle" => "gamma" },
|
||||
{ "handle" => "delta", "ok" => true },
|
||||
]
|
||||
|
||||
expectation = [
|
||||
{ "handle" => "alpha", "ok" => true },
|
||||
{ "handle" => "delta", "ok" => true },
|
||||
]
|
||||
|
||||
assert_equal(expectation, @filters.reject(input, "ok"))
|
||||
end
|
||||
|
||||
def test_reject_non_array_map_input
|
||||
assert_equal([], @filters.reject({ "foo" => "bar" }, "foo", "bar"))
|
||||
assert_equal([{ "foo" => "baz" }], @filters.reject({ "foo" => "baz" }, "foo", "bar"))
|
||||
end
|
||||
|
||||
def test_reject_indexable_but_non_map_value
|
||||
assert_equal([], @filters.reject(1, "ok", true))
|
||||
assert_equal([], @filters.reject(1, "ok"))
|
||||
end
|
||||
|
||||
def test_reject_non_boolean_value
|
||||
input = [
|
||||
{ "message" => "Bonjour!", "language" => "French" },
|
||||
{ "message" => "Hello!", "language" => "English" },
|
||||
]
|
||||
|
||||
assert_equal([{ "message" => "Hello!", "language" => "English" }], @filters.reject(input, "language", "French"))
|
||||
assert_equal([{ "message" => "Bonjour!", "language" => "French" }], @filters.reject(input, "language", "English"))
|
||||
end
|
||||
|
||||
def test_reject_array_of_only_unindexable_values
|
||||
assert_equal([], @filters.reject([nil, nil], "ok", true))
|
||||
assert_equal([], @filters.reject([nil, nil], "ok"))
|
||||
end
|
||||
|
||||
def test_reject_deep
|
||||
input = [
|
||||
{ "item" => { "handle" => "alpha", "ok" => true } },
|
||||
{ "item" => { "handle" => "beta", "ok" => false } },
|
||||
{ "item" => { "handle" => "gamma", "ok" => false } },
|
||||
{ "item" => { "handle" => "delta", "ok" => true } },
|
||||
]
|
||||
|
||||
expectation = [
|
||||
{ "item" => { "handle" => "alpha", "ok" => true } },
|
||||
{ "item" => { "handle" => "delta", "ok" => true } },
|
||||
]
|
||||
|
||||
assert_equal(expectation, @filters.reject(input, "item.ok", false))
|
||||
assert_equal(expectation, @filters.reject(input, "item.ok"))
|
||||
=======
|
||||
def test_where_deep_default_separator
|
||||
input = [
|
||||
{ "foo" => { "bar" => "baz", "handle" => "alpha" } },
|
||||
{ "foo" => { "bar" => "baz", "handle" => "beta" } },
|
||||
{ "foo" => { "bar" => "qux", "handle" => "charlie" } },
|
||||
]
|
||||
expectation = [
|
||||
{ "foo" => { "bar" => "baz", "handle" => "alpha" } },
|
||||
{ "foo" => { "bar" => "baz", "handle" => "beta" } },
|
||||
]
|
||||
assert_equal(expectation, @filters.where(input, "foo.bar", "baz", { "deep" => true }))
|
||||
end
|
||||
|
||||
def test_where_deep_custom_separator
|
||||
input = [
|
||||
{ "foo" => { "bar" => "baz", "handle" => "alpha" } },
|
||||
{ "foo" => { "bar" => "baz", "handle" => "beta" } },
|
||||
{ "foo" => { "bar" => "qux", "handle" => "charlie" } },
|
||||
]
|
||||
expectation = [
|
||||
{ "foo" => { "bar" => "baz", "handle" => "alpha" } },
|
||||
{ "foo" => { "bar" => "baz", "handle" => "beta" } },
|
||||
]
|
||||
assert_equal(expectation, @filters.where(input, "foo_bar", "baz", { "deep" => "_" }))
|
||||
end
|
||||
|
||||
def test_where_deep_off_by_default
|
||||
input = [
|
||||
{ "foo.bar" => "baz", "handle" => "alpha" },
|
||||
{ "foo.bar" => "baz", "handle" => "beta" },
|
||||
{ "foo.bar" => "qux", "handle" => "charlie" },
|
||||
]
|
||||
expectation = [
|
||||
{ "foo.bar" => "baz", "handle" => "alpha" },
|
||||
{ "foo.bar" => "baz", "handle" => "beta" },
|
||||
]
|
||||
assert_equal(expectation, @filters.where(input, "foo.bar", "baz"))
|
||||
>>>>>>> 2800d8dc (Add missing tests)
|
||||
end
|
||||
|
||||
def test_all_filters_never_raise_non_liquid_exception
|
||||
test_drop = TestDrop.new(value: "test")
|
||||
test_drop.context = Context.new
|
||||
@@ -1335,7 +926,6 @@ class StandardFiltersTest < Minitest::Test
|
||||
{ 1 => "bar" },
|
||||
["foo", 123, nil, true, false, Drop, ["foo"], { foo: "bar" }],
|
||||
]
|
||||
<<<<<<< HEAD
|
||||
StandardFilters.public_instance_methods(false).each do |method|
|
||||
arg_count = @filters.method(method).arity
|
||||
arg_count *= -1 if arg_count < 0
|
||||
@@ -1344,25 +934,6 @@ class StandardFiltersTest < Minitest::Test
|
||||
@filters.send(method, *args)
|
||||
rescue Liquid::Error
|
||||
nil
|
||||
=======
|
||||
test_types.each do |first|
|
||||
test_types.each do |second|
|
||||
test_types.each do |third|
|
||||
(@filters.methods - Object.methods).each do |method|
|
||||
arg_count = @filters.method(method).arity
|
||||
arg_count *= -1 if arg_count < 0
|
||||
inputs = [first]
|
||||
inputs << ([second] * (arg_count - 1)) if arg_count > 1
|
||||
inputs << ([third] * (arg_count - 1)) if arg_count > 2
|
||||
|
||||
begin
|
||||
@filters.send(method, *inputs)
|
||||
rescue Liquid::ArgumentError, Liquid::ZeroDivisionError
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
>>>>>>> f5e77b6d (Update test to support third argument)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1444,7 +1015,6 @@ class StandardFiltersTest < Minitest::Test
|
||||
assert(t.foo > 0)
|
||||
end
|
||||
|
||||
<<<<<<< HEAD
|
||||
def test_sum_of_floats
|
||||
input = [0.1, 0.2, 0.3]
|
||||
assert_equal(0.6, @filters.sum(input))
|
||||
@@ -1479,36 +1049,6 @@ class StandardFiltersTest < Minitest::Test
|
||||
assert_template_result("1.2", "{{ input | sum: 'quantity' }}", { "input" => input })
|
||||
assert_template_result("0.1", "{{ input | sum: 'weight' }}", { "input" => input })
|
||||
assert_template_result("0", "{{ input | sum: 'subtotal' }}", { "input" => input })
|
||||
=======
|
||||
def test_sum_deep_default_separator
|
||||
input = [
|
||||
{ "foo" => { "quantity" => 1 } },
|
||||
{ "foo" => { "quantity" => 2 } },
|
||||
{ "foo" => { "quantity" => 3 } },
|
||||
{ "foo" => { "quantity" => 4 } },
|
||||
]
|
||||
assert_equal(10, @filters.sum(input, "foo.quantity", { "deep" => true }))
|
||||
end
|
||||
|
||||
def test_sum_deep_custom_separator
|
||||
input = [
|
||||
{ "foo" => { "quantity" => 1 } },
|
||||
{ "foo" => { "quantity" => 2 } },
|
||||
{ "foo" => { "quantity" => 3 } },
|
||||
{ "foo" => { "quantity" => 4 } },
|
||||
]
|
||||
assert_equal(10, @filters.sum(input, "foo_quantity", { "deep" => "_" }))
|
||||
end
|
||||
|
||||
def test_sum_deep_off_by_default
|
||||
input = [
|
||||
{ "foo.quantity" => 1 },
|
||||
{ "foo.quantity" => 2 },
|
||||
{ "foo.quantity" => 3 },
|
||||
{ "foo.quantity" => 4 },
|
||||
]
|
||||
assert_equal(10, @filters.sum(input, "foo.quantity"))
|
||||
>>>>>>> 858428f2 (Initial new tests)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
Reference in New Issue
Block a user