Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test array filters added in Shopify/Liquid v5.7.2 #6

Merged
merged 8 commits into from
Mar 3, 2025
Merged

Conversation

jg-rp
Copy link
Owner

@jg-rp jg-rp commented Feb 11, 2025

This PR adds test cases for the following filters as they appear in version 5.7.2 of Shopify/Liquid.

  • reject
  • has
  • find
  • find_index

Note that these filters do not currently support arguments for testing/selecting child properties at arbitrary depths.

See Shopify/liquid#1906 and harttle/liquidjs#799

Some observations that hold true for all array filters (as of v5.7.2).

Optional argument

The second argument, target_value, is optional and it does not need to be a string, contrary to what the doc comments say.

Explicit nil

Explicitly testing for null/nil/None is not supported. Shopify/Liquid does not distinguish between the default value of nil and an explicit nil/null. For example, all templates are equivalent.

{{ a | has: 'foo' }}
{{ a | has: 'foo', nil}}
{{ a | has: 'foo', nosuchthing }}

Left values

Inputs are intended/assumed to be arrays of objects/hashes. If the input is an object/hash or primitive value (int, float, string, bool), it gets coerced to a single element array with the input value being the only item. With context data

{
    "a": [ {"foo": 42} ],
    "b": {"foo": 42}
}

Both of these templates are equivalent.

{{ a | find: 'foo' }}
{{ b | find: 'foo' }}

Arrays of strings

In Ruby, subscripting a string with another will return a substring if the first string contains the second. This leads to the following two templates resulting in true. There's at least one test case covering this behaviour in Shopify/Liquid, so this is known.

{{ 'foo' | has: 'oo' }}
{{ 'foo,bar' | split: ',' | has: 'oo' }}

And some odd results when filtering arrays of string values.

{{ 'x,y,cat' | split: ',' | reject: 'c' | join: ', ' }}

Early termination

If the input array contains a nil/null/None before a successful match, the result is nil/null/None. This example renders nothing when a is equal to ["x", nil, "z"].

{{ a | has: 'z' }}

Note that the where filter prior to version 5.7 behaved the same way.

Problematic integers

An exception is raised if the input array contains an integer and target_value is a string. And testing an input array of integers against an integer gives some as yet unexplained results.

require 'liquid'

source = <<LIQUID
{{ some_array | find: 3 }}
{{ some_array | find_index: 1 }}
LIQUID

template = Liquid::Template.parse(source, error_mode: :lax)
puts template.render!("some_array" => [-1, 42, 1, 2, 3, 4])

@jg-rp jg-rp marked this pull request as ready for review February 13, 2025 13:51
@jg-rp jg-rp merged commit af04c14 into main Mar 3, 2025
@jg-rp jg-rp deleted the new-array-filters branch March 3, 2025 07:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant