summaryrefslogtreecommitdiff
path: root/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration')
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/assign_test.rb48
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/blank_test.rb106
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/block_test.rb12
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/capture_test.rb50
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/context_test.rb32
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/document_test.rb19
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/drop_test.rb247
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/error_handling_test.rb260
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/filter_test.rb178
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/hash_ordering_test.rb23
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/output_test.rb123
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/parse_tree_visitor_test.rb247
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/parsing_quirks_test.rb122
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/render_profiling_test.rb154
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/security_test.rb80
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/standard_filter_test.rb776
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/break_tag_test.rb15
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/continue_tag_test.rb15
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/for_tag_test.rb410
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/if_else_tag_test.rb188
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/include_tag_test.rb253
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/increment_tag_test.rb23
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/raw_tag_test.rb31
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/standard_tag_test.rb296
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/statements_test.rb111
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/table_row_test.rb64
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/unless_else_tag_test.rb26
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/template_test.rb332
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/trim_mode_test.rb529
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/variable_test.rb96
30 files changed, 4866 insertions, 0 deletions
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/assign_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/assign_test.rb
new file mode 100644
index 0000000..5502289
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/assign_test.rb
@@ -0,0 +1,48 @@
+require 'test_helper'
+
+class AssignTest < Minitest::Test
+ include Liquid
+
+ def test_assign_with_hyphen_in_variable_name
+ template_source = <<-END_TEMPLATE
+ {% assign this-thing = 'Print this-thing' %}
+ {{ this-thing }}
+ END_TEMPLATE
+ template = Template.parse(template_source)
+ rendered = template.render!
+ assert_equal "Print this-thing", rendered.strip
+ end
+
+ def test_assigned_variable
+ assert_template_result('.foo.',
+ '{% assign foo = values %}.{{ foo[0] }}.',
+ 'values' => %w(foo bar baz))
+
+ assert_template_result('.bar.',
+ '{% assign foo = values %}.{{ foo[1] }}.',
+ 'values' => %w(foo bar baz))
+ end
+
+ def test_assign_with_filter
+ assert_template_result('.bar.',
+ '{% assign foo = values | split: "," %}.{{ foo[1] }}.',
+ 'values' => "foo,bar,baz")
+ end
+
+ def test_assign_syntax_error
+ assert_match_syntax_error(/assign/,
+ '{% assign foo not values %}.',
+ 'values' => "foo,bar,baz")
+ end
+
+ def test_assign_uses_error_mode
+ with_error_mode(:strict) do
+ assert_raises(SyntaxError) do
+ Template.parse("{% assign foo = ('X' | downcase) %}")
+ end
+ end
+ with_error_mode(:lax) do
+ assert Template.parse("{% assign foo = ('X' | downcase) %}")
+ end
+ end
+end # AssignTest
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/blank_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/blank_test.rb
new file mode 100644
index 0000000..e9b56df
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/blank_test.rb
@@ -0,0 +1,106 @@
+require 'test_helper'
+
+class FoobarTag < Liquid::Tag
+ def render(*args)
+ " "
+ end
+
+ Liquid::Template.register_tag('foobar', FoobarTag)
+end
+
+class BlankTestFileSystem
+ def read_template_file(template_path)
+ template_path
+ end
+end
+
+class BlankTest < Minitest::Test
+ include Liquid
+ N = 10
+
+ def wrap_in_for(body)
+ "{% for i in (1..#{N}) %}#{body}{% endfor %}"
+ end
+
+ def wrap_in_if(body)
+ "{% if true %}#{body}{% endif %}"
+ end
+
+ def wrap(body)
+ wrap_in_for(body) + wrap_in_if(body)
+ end
+
+ def test_new_tags_are_not_blank_by_default
+ assert_template_result(" " * N, wrap_in_for("{% foobar %}"))
+ end
+
+ def test_loops_are_blank
+ assert_template_result("", wrap_in_for(" "))
+ end
+
+ def test_if_else_are_blank
+ assert_template_result("", "{% if true %} {% elsif false %} {% else %} {% endif %}")
+ end
+
+ def test_unless_is_blank
+ assert_template_result("", wrap("{% unless true %} {% endunless %}"))
+ end
+
+ def test_mark_as_blank_only_during_parsing
+ assert_template_result(" " * (N + 1), wrap(" {% if false %} this never happens, but still, this block is not blank {% endif %}"))
+ end
+
+ def test_comments_are_blank
+ assert_template_result("", wrap(" {% comment %} whatever {% endcomment %} "))
+ end
+
+ def test_captures_are_blank
+ assert_template_result("", wrap(" {% capture foo %} whatever {% endcapture %} "))
+ end
+
+ def test_nested_blocks_are_blank_but_only_if_all_children_are
+ assert_template_result("", wrap(wrap(" ")))
+ assert_template_result("\n but this is not " * (N + 1),
+ wrap('{% if true %} {% comment %} this is blank {% endcomment %} {% endif %}
+ {% if true %} but this is not {% endif %}'))
+ end
+
+ def test_assigns_are_blank
+ assert_template_result("", wrap(' {% assign foo = "bar" %} '))
+ end
+
+ def test_whitespace_is_blank
+ assert_template_result("", wrap(" "))
+ assert_template_result("", wrap("\t"))
+ end
+
+ def test_whitespace_is_not_blank_if_other_stuff_is_present
+ body = " x "
+ assert_template_result(body * (N + 1), wrap(body))
+ end
+
+ def test_increment_is_not_blank
+ assert_template_result(" 0" * 2 * (N + 1), wrap("{% assign foo = 0 %} {% increment foo %} {% decrement foo %}"))
+ end
+
+ def test_cycle_is_not_blank
+ assert_template_result(" " * ((N + 1) / 2) + " ", wrap("{% cycle ' ', ' ' %}"))
+ end
+
+ def test_raw_is_not_blank
+ assert_template_result(" " * (N + 1), wrap(" {% raw %} {% endraw %}"))
+ end
+
+ def test_include_is_blank
+ Liquid::Template.file_system = BlankTestFileSystem.new
+ assert_template_result "foobar" * (N + 1), wrap("{% include 'foobar' %}")
+ assert_template_result " foobar " * (N + 1), wrap("{% include ' foobar ' %}")
+ assert_template_result " " * (N + 1), wrap(" {% include ' ' %} ")
+ end
+
+ def test_case_is_blank
+ assert_template_result("", wrap(" {% assign foo = 'bar' %} {% case foo %} {% when 'bar' %} {% when 'whatever' %} {% else %} {% endcase %} "))
+ assert_template_result("", wrap(" {% assign foo = 'else' %} {% case foo %} {% when 'bar' %} {% when 'whatever' %} {% else %} {% endcase %} "))
+ assert_template_result(" x " * (N + 1), wrap(" {% assign foo = 'else' %} {% case foo %} {% when 'bar' %} {% when 'whatever' %} {% else %} x {% endcase %} "))
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/block_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/block_test.rb
new file mode 100644
index 0000000..0824530
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/block_test.rb
@@ -0,0 +1,12 @@
+require 'test_helper'
+
+class BlockTest < Minitest::Test
+ include Liquid
+
+ def test_unexpected_end_tag
+ exc = assert_raises(SyntaxError) do
+ Template.parse("{% if true %}{% endunless %}")
+ end
+ assert_equal exc.message, "Liquid syntax error: 'endunless' is not a valid delimiter for if tags. use endif"
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/capture_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/capture_test.rb
new file mode 100644
index 0000000..8d965b3
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/capture_test.rb
@@ -0,0 +1,50 @@
+require 'test_helper'
+
+class CaptureTest < Minitest::Test
+ include Liquid
+
+ def test_captures_block_content_in_variable
+ assert_template_result("test string", "{% capture 'var' %}test string{% endcapture %}{{var}}", {})
+ end
+
+ def test_capture_with_hyphen_in_variable_name
+ template_source = <<-END_TEMPLATE
+ {% capture this-thing %}Print this-thing{% endcapture %}
+ {{ this-thing }}
+ END_TEMPLATE
+ template = Template.parse(template_source)
+ rendered = template.render!
+ assert_equal "Print this-thing", rendered.strip
+ end
+
+ def test_capture_to_variable_from_outer_scope_if_existing
+ template_source = <<-END_TEMPLATE
+ {% assign var = '' %}
+ {% if true %}
+ {% capture var %}first-block-string{% endcapture %}
+ {% endif %}
+ {% if true %}
+ {% capture var %}test-string{% endcapture %}
+ {% endif %}
+ {{var}}
+ END_TEMPLATE
+ template = Template.parse(template_source)
+ rendered = template.render!
+ assert_equal "test-string", rendered.gsub(/\s/, '')
+ end
+
+ def test_assigning_from_capture
+ template_source = <<-END_TEMPLATE
+ {% assign first = '' %}
+ {% assign second = '' %}
+ {% for number in (1..3) %}
+ {% capture first %}{{number}}{% endcapture %}
+ {% assign second = first %}
+ {% endfor %}
+ {{ first }}-{{ second }}
+ END_TEMPLATE
+ template = Template.parse(template_source)
+ rendered = template.render!
+ assert_equal "3-3", rendered.gsub(/\s/, '')
+ end
+end # CaptureTest
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/context_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/context_test.rb
new file mode 100644
index 0000000..2d109bb
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/context_test.rb
@@ -0,0 +1,32 @@
+require 'test_helper'
+
+class ContextTest < Minitest::Test
+ include Liquid
+
+ def test_override_global_filter
+ global = Module.new do
+ def notice(output)
+ "Global #{output}"
+ end
+ end
+
+ local = Module.new do
+ def notice(output)
+ "Local #{output}"
+ end
+ end
+
+ with_global_filter(global) do
+ assert_equal 'Global test', Template.parse("{{'test' | notice }}").render!
+ assert_equal 'Local test', Template.parse("{{'test' | notice }}").render!({}, filters: [local])
+ end
+ end
+
+ def test_has_key_will_not_add_an_error_for_missing_keys
+ with_error_mode :strict do
+ context = Context.new
+ context.key?('unknown')
+ assert_empty context.errors
+ end
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/document_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/document_test.rb
new file mode 100644
index 0000000..bcc4a21
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/document_test.rb
@@ -0,0 +1,19 @@
+require 'test_helper'
+
+class DocumentTest < Minitest::Test
+ include Liquid
+
+ def test_unexpected_outer_tag
+ exc = assert_raises(SyntaxError) do
+ Template.parse("{% else %}")
+ end
+ assert_equal exc.message, "Liquid syntax error: Unexpected outer 'else' tag"
+ end
+
+ def test_unknown_tag
+ exc = assert_raises(SyntaxError) do
+ Template.parse("{% foo %}")
+ end
+ assert_equal exc.message, "Liquid syntax error: Unknown tag 'foo'"
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/drop_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/drop_test.rb
new file mode 100644
index 0000000..723fe04
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/drop_test.rb
@@ -0,0 +1,247 @@
+require 'test_helper'
+
+class ContextDrop < Liquid::Drop
+ def scopes
+ @context.scopes.size
+ end
+
+ def scopes_as_array
+ (1..@context.scopes.size).to_a
+ end
+
+ def loop_pos
+ @context['forloop.index']
+ end
+
+ def liquid_method_missing(method)
+ @context[method]
+ end
+end
+
+class ProductDrop < Liquid::Drop
+ class TextDrop < Liquid::Drop
+ def array
+ ['text1', 'text2']
+ end
+
+ def text
+ 'text1'
+ end
+ end
+
+ class CatchallDrop < Liquid::Drop
+ def liquid_method_missing(method)
+ 'catchall_method: ' << method.to_s
+ end
+ end
+
+ def texts
+ TextDrop.new
+ end
+
+ def catchall
+ CatchallDrop.new
+ end
+
+ def context
+ ContextDrop.new
+ end
+
+ def user_input
+ "foo"
+ end
+
+ protected
+
+ def callmenot
+ "protected"
+ end
+end
+
+class EnumerableDrop < Liquid::Drop
+ def liquid_method_missing(method)
+ method
+ end
+
+ def size
+ 3
+ end
+
+ def first
+ 1
+ end
+
+ def count
+ 3
+ end
+
+ def min
+ 1
+ end
+
+ def max
+ 3
+ end
+
+ def each
+ yield 1
+ yield 2
+ yield 3
+ end
+end
+
+class RealEnumerableDrop < Liquid::Drop
+ include Enumerable
+
+ def liquid_method_missing(method)
+ method
+ end
+
+ def each
+ yield 1
+ yield 2
+ yield 3
+ end
+end
+
+class DropsTest < Minitest::Test
+ include Liquid
+
+ def test_product_drop
+ tpl = Liquid::Template.parse(' ')
+ assert_equal ' ', tpl.render!('product' => ProductDrop.new)
+ end
+
+ def test_drop_does_only_respond_to_whitelisted_methods
+ assert_equal "", Liquid::Template.parse("{{ product.inspect }}").render!('product' => ProductDrop.new)
+ assert_equal "", Liquid::Template.parse("{{ product.pretty_inspect }}").render!('product' => ProductDrop.new)
+ assert_equal "", Liquid::Template.parse("{{ product.whatever }}").render!('product' => ProductDrop.new)
+ assert_equal "", Liquid::Template.parse('{{ product | map: "inspect" }}').render!('product' => ProductDrop.new)
+ assert_equal "", Liquid::Template.parse('{{ product | map: "pretty_inspect" }}').render!('product' => ProductDrop.new)
+ assert_equal "", Liquid::Template.parse('{{ product | map: "whatever" }}').render!('product' => ProductDrop.new)
+ end
+
+ def test_drops_respond_to_to_liquid
+ assert_equal "text1", Liquid::Template.parse("{{ product.to_liquid.texts.text }}").render!('product' => ProductDrop.new)
+ assert_equal "text1", Liquid::Template.parse('{{ product | map: "to_liquid" | map: "texts" | map: "text" }}').render!('product' => ProductDrop.new)
+ end
+
+ def test_text_drop
+ output = Liquid::Template.parse(' {{ product.texts.text }} ').render!('product' => ProductDrop.new)
+ assert_equal ' text1 ', output
+ end
+
+ def test_catchall_unknown_method
+ output = Liquid::Template.parse(' {{ product.catchall.unknown }} ').render!('product' => ProductDrop.new)
+ assert_equal ' catchall_method: unknown ', output
+ end
+
+ def test_catchall_integer_argument_drop
+ output = Liquid::Template.parse(' {{ product.catchall[8] }} ').render!('product' => ProductDrop.new)
+ assert_equal ' catchall_method: 8 ', output
+ end
+
+ def test_text_array_drop
+ output = Liquid::Template.parse('{% for text in product.texts.array %} {{text}} {% endfor %}').render!('product' => ProductDrop.new)
+ assert_equal ' text1 text2 ', output
+ end
+
+ def test_context_drop
+ output = Liquid::Template.parse(' {{ context.bar }} ').render!('context' => ContextDrop.new, 'bar' => "carrot")
+ assert_equal ' carrot ', output
+ end
+
+ def test_nested_context_drop
+ output = Liquid::Template.parse(' {{ product.context.foo }} ').render!('product' => ProductDrop.new, 'foo' => "monkey")
+ assert_equal ' monkey ', output
+ end
+
+ def test_protected
+ output = Liquid::Template.parse(' {{ product.callmenot }} ').render!('product' => ProductDrop.new)
+ assert_equal ' ', output
+ end
+
+ def test_object_methods_not_allowed
+ [:dup, :clone, :singleton_class, :eval, :class_eval, :inspect].each do |method|
+ output = Liquid::Template.parse(" {{ product.#{method} }} ").render!('product' => ProductDrop.new)
+ assert_equal ' ', output
+ end
+ end
+
+ def test_scope
+ assert_equal '1', Liquid::Template.parse('{{ context.scopes }}').render!('context' => ContextDrop.new)
+ assert_equal '2', Liquid::Template.parse('{%for i in dummy%}{{ context.scopes }}{%endfor%}').render!('context' => ContextDrop.new, 'dummy' => [1])
+ assert_equal '3', Liquid::Template.parse('{%for i in dummy%}{%for i in dummy%}{{ context.scopes }}{%endfor%}{%endfor%}').render!('context' => ContextDrop.new, 'dummy' => [1])
+ end
+
+ def test_scope_though_proc
+ assert_equal '1', Liquid::Template.parse('{{ s }}').render!('context' => ContextDrop.new, 's' => proc{ |c| c['context.scopes'] })
+ assert_equal '2', Liquid::Template.parse('{%for i in dummy%}{{ s }}{%endfor%}').render!('context' => ContextDrop.new, 's' => proc{ |c| c['context.scopes'] }, 'dummy' => [1])
+ assert_equal '3', Liquid::Template.parse('{%for i in dummy%}{%for i in dummy%}{{ s }}{%endfor%}{%endfor%}').render!('context' => ContextDrop.new, 's' => proc{ |c| c['context.scopes'] }, 'dummy' => [1])
+ end
+
+ def test_scope_with_assigns
+ assert_equal 'variable', Liquid::Template.parse('{% assign a = "variable"%}{{a}}').render!('context' => ContextDrop.new)
+ assert_equal 'variable', Liquid::Template.parse('{% assign a = "variable"%}{%for i in dummy%}{{a}}{%endfor%}').render!('context' => ContextDrop.new, 'dummy' => [1])
+ assert_equal 'test', Liquid::Template.parse('{% assign header_gif = "test"%}{{header_gif}}').render!('context' => ContextDrop.new)
+ assert_equal 'test', Liquid::Template.parse("{% assign header_gif = 'test'%}{{header_gif}}").render!('context' => ContextDrop.new)
+ end
+
+ def test_scope_from_tags
+ assert_equal '1', Liquid::Template.parse('{% for i in context.scopes_as_array %}{{i}}{% endfor %}').render!('context' => ContextDrop.new, 'dummy' => [1])
+ assert_equal '12', Liquid::Template.parse('{%for a in dummy%}{% for i in context.scopes_as_array %}{{i}}{% endfor %}{% endfor %}').render!('context' => ContextDrop.new, 'dummy' => [1])
+ assert_equal '123', Liquid::Template.parse('{%for a in dummy%}{%for a in dummy%}{% for i in context.scopes_as_array %}{{i}}{% endfor %}{% endfor %}{% endfor %}').render!('context' => ContextDrop.new, 'dummy' => [1])
+ end
+
+ def test_access_context_from_drop
+ assert_equal '123', Liquid::Template.parse('{%for a in dummy%}{{ context.loop_pos }}{% endfor %}').render!('context' => ContextDrop.new, 'dummy' => [1, 2, 3])
+ end
+
+ def test_enumerable_drop
+ assert_equal '123', Liquid::Template.parse('{% for c in collection %}{{c}}{% endfor %}').render!('collection' => EnumerableDrop.new)
+ end
+
+ def test_enumerable_drop_size
+ assert_equal '3', Liquid::Template.parse('{{collection.size}}').render!('collection' => EnumerableDrop.new)
+ end
+
+ def test_enumerable_drop_will_invoke_liquid_method_missing_for_clashing_method_names
+ ["select", "each", "map", "cycle"].each do |method|
+ assert_equal method.to_s, Liquid::Template.parse("{{collection.#{method}}}").render!('collection' => EnumerableDrop.new)
+ assert_equal method.to_s, Liquid::Template.parse("{{collection[\"#{method}\"]}}").render!('collection' => EnumerableDrop.new)
+ assert_equal method.to_s, Liquid::Template.parse("{{collection.#{method}}}").render!('collection' => RealEnumerableDrop.new)
+ assert_equal method.to_s, Liquid::Template.parse("{{collection[\"#{method}\"]}}").render!('collection' => RealEnumerableDrop.new)
+ end
+ end
+
+ def test_some_enumerable_methods_still_get_invoked
+ [ :count, :max ].each do |method|
+ assert_equal "3", Liquid::Template.parse("{{collection.#{method}}}").render!('collection' => RealEnumerableDrop.new)
+ assert_equal "3", Liquid::Template.parse("{{collection[\"#{method}\"]}}").render!('collection' => RealEnumerableDrop.new)
+ assert_equal "3", Liquid::Template.parse("{{collection.#{method}}}").render!('collection' => EnumerableDrop.new)
+ assert_equal "3", Liquid::Template.parse("{{collection[\"#{method}\"]}}").render!('collection' => EnumerableDrop.new)
+ end
+
+ assert_equal "yes", Liquid::Template.parse("{% if collection contains 3 %}yes{% endif %}").render!('collection' => RealEnumerableDrop.new)
+
+ [ :min, :first ].each do |method|
+ assert_equal "1", Liquid::Template.parse("{{collection.#{method}}}").render!('collection' => RealEnumerableDrop.new)
+ assert_equal "1", Liquid::Template.parse("{{collection[\"#{method}\"]}}").render!('collection' => RealEnumerableDrop.new)
+ assert_equal "1", Liquid::Template.parse("{{collection.#{method}}}").render!('collection' => EnumerableDrop.new)
+ assert_equal "1", Liquid::Template.parse("{{collection[\"#{method}\"]}}").render!('collection' => EnumerableDrop.new)
+ end
+ end
+
+ def test_empty_string_value_access
+ assert_equal '', Liquid::Template.parse('{{ product[value] }}').render!('product' => ProductDrop.new, 'value' => '')
+ end
+
+ def test_nil_value_access
+ assert_equal '', Liquid::Template.parse('{{ product[value] }}').render!('product' => ProductDrop.new, 'value' => nil)
+ end
+
+ def test_default_to_s_on_drops
+ assert_equal 'ProductDrop', Liquid::Template.parse("{{ product }}").render!('product' => ProductDrop.new)
+ assert_equal 'EnumerableDrop', Liquid::Template.parse('{{ collection }}').render!('collection' => EnumerableDrop.new)
+ end
+end # DropsTest
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/error_handling_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/error_handling_test.rb
new file mode 100644
index 0000000..b2d186c
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/error_handling_test.rb
@@ -0,0 +1,260 @@
+require 'test_helper'
+
+class ErrorHandlingTest < Minitest::Test
+ include Liquid
+
+ def test_templates_parsed_with_line_numbers_renders_them_in_errors
+ template = <<-LIQUID
+ Hello,
+
+ {{ errors.standard_error }} will raise a standard error.
+
+ Bla bla test.
+
+ {{ errors.syntax_error }} will raise a syntax error.
+
+ This is an argument error: {{ errors.argument_error }}
+
+ Bla.
+ LIQUID
+
+ expected = <<-TEXT
+ Hello,
+
+ Liquid error (line 3): standard error will raise a standard error.
+
+ Bla bla test.
+
+ Liquid syntax error (line 7): syntax error will raise a syntax error.
+
+ This is an argument error: Liquid error (line 9): argument error
+
+ Bla.
+ TEXT
+
+ output = Liquid::Template.parse(template, line_numbers: true).render('errors' => ErrorDrop.new)
+ assert_equal expected, output
+ end
+
+ def test_standard_error
+ template = Liquid::Template.parse(' {{ errors.standard_error }} ')
+ assert_equal ' Liquid error: standard error ', template.render('errors' => ErrorDrop.new)
+
+ assert_equal 1, template.errors.size
+ assert_equal StandardError, template.errors.first.class
+ end
+
+ def test_syntax
+ template = Liquid::Template.parse(' {{ errors.syntax_error }} ')
+ assert_equal ' Liquid syntax error: syntax error ', template.render('errors' => ErrorDrop.new)
+
+ assert_equal 1, template.errors.size
+ assert_equal SyntaxError, template.errors.first.class
+ end
+
+ def test_argument
+ template = Liquid::Template.parse(' {{ errors.argument_error }} ')
+ assert_equal ' Liquid error: argument error ', template.render('errors' => ErrorDrop.new)
+
+ assert_equal 1, template.errors.size
+ assert_equal ArgumentError, template.errors.first.class
+ end
+
+ def test_missing_endtag_parse_time_error
+ assert_raises(Liquid::SyntaxError) do
+ Liquid::Template.parse(' {% for a in b %} ... ')
+ end
+ end
+
+ def test_unrecognized_operator
+ with_error_mode(:strict) do
+ assert_raises(SyntaxError) do
+ Liquid::Template.parse(' {% if 1 =! 2 %}ok{% endif %} ')
+ end
+ end
+ end
+
+ def test_lax_unrecognized_operator
+ template = Liquid::Template.parse(' {% if 1 =! 2 %}ok{% endif %} ', error_mode: :lax)
+ assert_equal ' Liquid error: Unknown operator =! ', template.render
+ assert_equal 1, template.errors.size
+ assert_equal Liquid::ArgumentError, template.errors.first.class
+ end
+
+ def test_with_line_numbers_adds_numbers_to_parser_errors
+ err = assert_raises(SyntaxError) do
+ Liquid::Template.parse(%q(
+ foobar
+
+ {% "cat" | foobar %}
+
+ bla
+ ),
+ line_numbers: true
+ )
+ end
+
+ assert_match(/Liquid syntax error \(line 4\)/, err.message)
+ end
+
+ def test_with_line_numbers_adds_numbers_to_parser_errors_with_whitespace_trim
+ err = assert_raises(SyntaxError) do
+ Liquid::Template.parse(%q(
+ foobar
+
+ {%- "cat" | foobar -%}
+
+ bla
+ ),
+ line_numbers: true
+ )
+ end
+
+ assert_match(/Liquid syntax error \(line 4\)/, err.message)
+ end
+
+ def test_parsing_warn_with_line_numbers_adds_numbers_to_lexer_errors
+ template = Liquid::Template.parse('
+ foobar
+
+ {% if 1 =! 2 %}ok{% endif %}
+
+ bla
+ ',
+ error_mode: :warn,
+ line_numbers: true
+ )
+
+ assert_equal ['Liquid syntax error (line 4): Unexpected character = in "1 =! 2"'],
+ template.warnings.map(&:message)
+ end
+
+ def test_parsing_strict_with_line_numbers_adds_numbers_to_lexer_errors
+ err = assert_raises(SyntaxError) do
+ Liquid::Template.parse('
+ foobar
+
+ {% if 1 =! 2 %}ok{% endif %}
+
+ bla
+ ',
+ error_mode: :strict,
+ line_numbers: true
+ )
+ end
+
+ assert_equal 'Liquid syntax error (line 4): Unexpected character = in "1 =! 2"', err.message
+ end
+
+ def test_syntax_errors_in_nested_blocks_have_correct_line_number
+ err = assert_raises(SyntaxError) do
+ Liquid::Template.parse('
+ foobar
+
+ {% if 1 != 2 %}
+ {% foo %}
+ {% endif %}
+
+ bla
+ ',
+ line_numbers: true
+ )
+ end
+
+ assert_equal "Liquid syntax error (line 5): Unknown tag 'foo'", err.message
+ end
+
+ def test_strict_error_messages
+ err = assert_raises(SyntaxError) do
+ Liquid::Template.parse(' {% if 1 =! 2 %}ok{% endif %} ', error_mode: :strict)
+ end
+ assert_equal 'Liquid syntax error: Unexpected character = in "1 =! 2"', err.message
+
+ err = assert_raises(SyntaxError) do
+ Liquid::Template.parse('{{%%%}}', error_mode: :strict)
+ end
+ assert_equal 'Liquid syntax error: Unexpected character % in "{{%%%}}"', err.message
+ end
+
+ def test_warnings
+ template = Liquid::Template.parse('{% if ~~~ %}{{%%%}}{% else %}{{ hello. }}{% endif %}', error_mode: :warn)
+ assert_equal 3, template.warnings.size
+ assert_equal 'Unexpected character ~ in "~~~"', template.warnings[0].to_s(false)
+ assert_equal 'Unexpected character % in "{{%%%}}"', template.warnings[1].to_s(false)
+ assert_equal 'Expected id but found end_of_string in "{{ hello. }}"', template.warnings[2].to_s(false)
+ assert_equal '', template.render
+ end
+
+ def test_warning_line_numbers
+ template = Liquid::Template.parse("{% if ~~~ %}\n{{%%%}}{% else %}\n{{ hello. }}{% endif %}", error_mode: :warn, line_numbers: true)
+ assert_equal 'Liquid syntax error (line 1): Unexpected character ~ in "~~~"', template.warnings[0].message
+ assert_equal 'Liquid syntax error (line 2): Unexpected character % in "{{%%%}}"', template.warnings[1].message
+ assert_equal 'Liquid syntax error (line 3): Expected id but found end_of_string in "{{ hello. }}"', template.warnings[2].message
+ assert_equal 3, template.warnings.size
+ assert_equal [1, 2, 3], template.warnings.map(&:line_number)
+ end
+
+ # Liquid should not catch Exceptions that are not subclasses of StandardError, like Interrupt and NoMemoryError
+ def test_exceptions_propagate
+ assert_raises Exception do
+ template = Liquid::Template.parse('{{ errors.exception }}')
+ template.render('errors' => ErrorDrop.new)
+ end
+ end
+
+ def test_default_exception_renderer_with_internal_error
+ template = Liquid::Template.parse('This is a runtime error: {{ errors.runtime_error }}', line_numbers: true)
+
+ output = template.render({ 'errors' => ErrorDrop.new })
+
+ assert_equal 'This is a runtime error: Liquid error (line 1): internal', output
+ assert_equal [Liquid::InternalError], template.errors.map(&:class)
+ end
+
+ def test_setting_default_exception_renderer
+ old_exception_renderer = Liquid::Template.default_exception_renderer
+ exceptions = []
+ Liquid::Template.default_exception_renderer = ->(e) { exceptions << e; '' }
+ template = Liquid::Template.parse('This is a runtime error: {{ errors.argument_error }}')
+
+ output = template.render({ 'errors' => ErrorDrop.new })
+
+ assert_equal 'This is a runtime error: ', output
+ assert_equal [Liquid::ArgumentError], template.errors.map(&:class)
+ ensure
+ Liquid::Template.default_exception_renderer = old_exception_renderer if old_exception_renderer
+ end
+
+ def test_exception_renderer_exposing_non_liquid_error
+ template = Liquid::Template.parse('This is a runtime error: {{ errors.runtime_error }}', line_numbers: true)
+ exceptions = []
+ handler = ->(e) { exceptions << e; e.cause }
+
+ output = template.render({ 'errors' => ErrorDrop.new }, exception_renderer: handler)
+
+ assert_equal 'This is a runtime error: runtime error', output
+ assert_equal [Liquid::InternalError], exceptions.map(&:class)
+ assert_equal exceptions, template.errors
+ assert_equal '#<RuntimeError: runtime error>', exceptions.first.cause.inspect
+ end
+
+ class TestFileSystem
+ def read_template_file(template_path)
+ "{{ errors.argument_error }}"
+ end
+ end
+
+ def test_included_template_name_with_line_numbers
+ old_file_system = Liquid::Template.file_system
+
+ begin
+ Liquid::Template.file_system = TestFileSystem.new
+ template = Liquid::Template.parse("Argument error:\n{% include 'product' %}", line_numbers: true)
+ page = template.render('errors' => ErrorDrop.new)
+ ensure
+ Liquid::Template.file_system = old_file_system
+ end
+ assert_equal "Argument error:\nLiquid error (product line 1): argument error", page
+ assert_equal "product", template.errors.first.template_name
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/filter_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/filter_test.rb
new file mode 100644
index 0000000..d3c880e
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/filter_test.rb
@@ -0,0 +1,178 @@
+require 'test_helper'
+
+module MoneyFilter
+ def money(input)
+ sprintf(' %d$ ', input)
+ end
+
+ def money_with_underscore(input)
+ sprintf(' %d$ ', input)
+ end
+end
+
+module CanadianMoneyFilter
+ def money(input)
+ sprintf(' %d$ CAD ', input)
+ end
+end
+
+module SubstituteFilter
+ def substitute(input, params = {})
+ input.gsub(/%\{(\w+)\}/) { |match| params[$1] }
+ end
+end
+
+class FiltersTest < Minitest::Test
+ include Liquid
+
+ module OverrideObjectMethodFilter
+ def tap(input)
+ "tap overridden"
+ end
+ end
+
+ def setup
+ @context = Context.new
+ end
+
+ def test_local_filter
+ @context['var'] = 1000
+ @context.add_filters(MoneyFilter)
+
+ assert_equal ' 1000$ ', Template.parse("{{var | money}}").render(@context)
+ end
+
+ def test_underscore_in_filter_name
+ @context['var'] = 1000
+ @context.add_filters(MoneyFilter)
+ assert_equal ' 1000$ ', Template.parse("{{var | money_with_underscore}}").render(@context)
+ end
+
+ def test_second_filter_overwrites_first
+ @context['var'] = 1000
+ @context.add_filters(MoneyFilter)
+ @context.add_filters(CanadianMoneyFilter)
+
+ assert_equal ' 1000$ CAD ', Template.parse("{{var | money}}").render(@context)
+ end
+
+ def test_size
+ @context['var'] = 'abcd'
+ @context.add_filters(MoneyFilter)
+
+ assert_equal '4', Template.parse("{{var | size}}").render(@context)
+ end
+
+ def test_join
+ @context['var'] = [1, 2, 3, 4]
+
+ assert_equal "1 2 3 4", Template.parse("{{var | join}}").render(@context)
+ end
+
+ def test_sort
+ @context['value'] = 3
+ @context['numbers'] = [2, 1, 4, 3]
+ @context['words'] = ['expected', 'as', 'alphabetic']
+ @context['arrays'] = ['flower', 'are']
+ @context['case_sensitive'] = ['sensitive', 'Expected', 'case']
+
+ assert_equal '1 2 3 4', Template.parse("{{numbers | sort | join}}").render(@context)
+ assert_equal 'alphabetic as expected', Template.parse("{{words | sort | join}}").render(@context)
+ assert_equal '3', Template.parse("{{value | sort}}").render(@context)
+ assert_equal 'are flower', Template.parse("{{arrays | sort | join}}").render(@context)
+ assert_equal 'Expected case sensitive', Template.parse("{{case_sensitive | sort | join}}").render(@context)
+ end
+
+ def test_sort_natural
+ @context['words'] = ['case', 'Assert', 'Insensitive']
+ @context['hashes'] = [{ 'a' => 'A' }, { 'a' => 'b' }, { 'a' => 'C' }]
+ @context['objects'] = [TestObject.new('A'), TestObject.new('b'), TestObject.new('C')]
+
+ # Test strings
+ assert_equal 'Assert case Insensitive', Template.parse("{{words | sort_natural | join}}").render(@context)
+
+ # Test hashes
+ assert_equal 'A b C', Template.parse("{{hashes | sort_natural: 'a' | map: 'a' | join}}").render(@context)
+
+ # Test objects
+ assert_equal 'A b C', Template.parse("{{objects | sort_natural: 'a' | map: 'a' | join}}").render(@context)
+ end
+
+ def test_compact
+ @context['words'] = ['a', nil, 'b', nil, 'c']
+ @context['hashes'] = [{ 'a' => 'A' }, { 'a' => nil }, { 'a' => 'C' }]
+ @context['objects'] = [TestObject.new('A'), TestObject.new(nil), TestObject.new('C')]
+
+ # Test strings
+ assert_equal 'a b c', Template.parse("{{words | compact | join}}").render(@context)
+
+ # Test hashes
+ assert_equal 'A C', Template.parse("{{hashes | compact: 'a' | map: 'a' | join}}").render(@context)
+
+ # Test objects
+ assert_equal 'A C', Template.parse("{{objects | compact: 'a' | map: 'a' | join}}").render(@context)
+ end
+
+ def test_strip_html
+ @context['var'] = "<b>bla blub</a>"
+
+ assert_equal "bla blub", Template.parse("{{ var | strip_html }}").render(@context)
+ end
+
+ def test_strip_html_ignore_comments_with_html
+ @context['var'] = "<!-- split and some <ul> tag --><b>bla blub</a>"
+
+ assert_equal "bla blub", Template.parse("{{ var | strip_html }}").render(@context)
+ end
+
+ def test_capitalize
+ @context['var'] = "blub"
+
+ assert_equal "Blub", Template.parse("{{ var | capitalize }}").render(@context)
+ end
+
+ def test_nonexistent_filter_is_ignored
+ @context['var'] = 1000
+
+ assert_equal '1000', Template.parse("{{ var | xyzzy }}").render(@context)
+ end
+
+ def test_filter_with_keyword_arguments
+ @context['surname'] = 'john'
+ @context['input'] = 'hello %{first_name}, %{last_name}'
+ @context.add_filters(SubstituteFilter)
+ output = Template.parse(%({{ input | substitute: first_name: surname, last_name: 'doe' }})).render(@context)
+ assert_equal 'hello john, doe', output
+ end
+
+ def test_override_object_method_in_filter
+ assert_equal "tap overridden", Template.parse("{{var | tap}}").render!({ 'var' => 1000 }, filters: [OverrideObjectMethodFilter])
+
+ # tap still treated as a non-existent filter
+ assert_equal "1000", Template.parse("{{var | tap}}").render!({ 'var' => 1000 })
+ end
+end
+
+class FiltersInTemplate < Minitest::Test
+ include Liquid
+
+ def test_local_global
+ with_global_filter(MoneyFilter) do
+ assert_equal " 1000$ ", Template.parse("{{1000 | money}}").render!(nil, nil)
+ assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render!(nil, filters: CanadianMoneyFilter)
+ assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render!(nil, filters: [CanadianMoneyFilter])
+ end
+ end
+
+ def test_local_filter_with_deprecated_syntax
+ assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render!(nil, CanadianMoneyFilter)
+ assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render!(nil, [CanadianMoneyFilter])
+ end
+end # FiltersTest
+
+class TestObject < Liquid::Drop
+ attr_accessor :a
+ def initialize(a)
+ @a = a
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/hash_ordering_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/hash_ordering_test.rb
new file mode 100644
index 0000000..dfc1c29
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/hash_ordering_test.rb
@@ -0,0 +1,23 @@
+require 'test_helper'
+
+class HashOrderingTest < Minitest::Test
+ module MoneyFilter
+ def money(input)
+ sprintf(' %d$ ', input)
+ end
+ end
+
+ module CanadianMoneyFilter
+ def money(input)
+ sprintf(' %d$ CAD ', input)
+ end
+ end
+
+ include Liquid
+
+ def test_global_register_order
+ with_global_filter(MoneyFilter, CanadianMoneyFilter) do
+ assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render(nil, nil)
+ end
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/output_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/output_test.rb
new file mode 100644
index 0000000..b4cf9d7
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/output_test.rb
@@ -0,0 +1,123 @@
+require 'test_helper'
+
+module FunnyFilter
+ def make_funny(input)
+ 'LOL'
+ end
+
+ def cite_funny(input)
+ "LOL: #{input}"
+ end
+
+ def add_smiley(input, smiley = ":-)")
+ "#{input} #{smiley}"
+ end
+
+ def add_tag(input, tag = "p", id = "foo")
+ %(<#{tag} id="#{id}">#{input}</#{tag}>)
+ end
+
+ def paragraph(input)
+ "<p>#{input}</p>"
+ end
+
+ def link_to(name, url)
+ %(<a href="#{url}">#{name}</a>)
+ end
+end
+
+class OutputTest < Minitest::Test
+ include Liquid
+
+ def setup
+ @assigns = {
+ 'best_cars' => 'bmw',
+ 'car' => { 'bmw' => 'good', 'gm' => 'bad' }
+ }
+ end
+
+ def test_variable
+ text = %( {{best_cars}} )
+
+ expected = %( bmw )
+ assert_equal expected, Template.parse(text).render!(@assigns)
+ end
+
+ def test_variable_traversing_with_two_brackets
+ text = %({{ site.data.menu[include.menu][include.locale] }})
+ assert_equal "it works!", Template.parse(text).render!(
+ "site" => { "data" => { "menu" => { "foo" => { "bar" => "it works!" } } } },
+ "include" => { "menu" => "foo", "locale" => "bar" }
+ )
+ end
+
+ def test_variable_traversing
+ text = %( {{car.bmw}} {{car.gm}} {{car.bmw}} )
+
+ expected = %( good bad good )
+ assert_equal expected, Template.parse(text).render!(@assigns)
+ end
+
+ def test_variable_piping
+ text = %( {{ car.gm | make_funny }} )
+ expected = %( LOL )
+
+ assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
+ end
+
+ def test_variable_piping_with_input
+ text = %( {{ car.gm | cite_funny }} )
+ expected = %( LOL: bad )
+
+ assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
+ end
+
+ def test_variable_piping_with_args
+ text = %! {{ car.gm | add_smiley : ':-(' }} !
+ expected = %| bad :-( |
+
+ assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
+ end
+
+ def test_variable_piping_with_no_args
+ text = %( {{ car.gm | add_smiley }} )
+ expected = %| bad :-) |
+
+ assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
+ end
+
+ def test_multiple_variable_piping_with_args
+ text = %! {{ car.gm | add_smiley : ':-(' | add_smiley : ':-('}} !
+ expected = %| bad :-( :-( |
+
+ assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
+ end
+
+ def test_variable_piping_with_multiple_args
+ text = %( {{ car.gm | add_tag : 'span', 'bar'}} )
+ expected = %( <span id="bar">bad</span> )
+
+ assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
+ end
+
+ def test_variable_piping_with_variable_args
+ text = %( {{ car.gm | add_tag : 'span', car.bmw}} )
+ expected = %( <span id="good">bad</span> )
+
+ assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
+ end
+
+ def test_multiple_pipings
+ text = %( {{ best_cars | cite_funny | paragraph }} )
+ expected = %( <p>LOL: bmw</p> )
+
+ assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
+ end
+
+ def test_link_to
+ text = %( {{ 'Typo' | link_to: 'http://typo.leetsoft.com' }} )
+ expected = %( <a href="http://typo.leetsoft.com">Typo</a> )
+
+ assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
+ end
+end # OutputTest
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/parse_tree_visitor_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/parse_tree_visitor_test.rb
new file mode 100644
index 0000000..933dbc3
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/parse_tree_visitor_test.rb
@@ -0,0 +1,247 @@
+# frozen_string_literal: true
+
+require 'test_helper'
+
+class ParseTreeVisitorTest < Minitest::Test
+ include Liquid
+
+ def test_variable
+ assert_equal(
+ ["test"],
+ visit(%({{ test }}))
+ )
+ end
+
+ def test_varible_with_filter
+ assert_equal(
+ ["test", "infilter"],
+ visit(%({{ test | split: infilter }}))
+ )
+ end
+
+ def test_dynamic_variable
+ assert_equal(
+ ["test", "inlookup"],
+ visit(%({{ test[inlookup] }}))
+ )
+ end
+
+ def test_if_condition
+ assert_equal(
+ ["test"],
+ visit(%({% if test %}{% endif %}))
+ )
+ end
+
+ def test_complex_if_condition
+ assert_equal(
+ ["test"],
+ visit(%({% if 1 == 1 and 2 == test %}{% endif %}))
+ )
+ end
+
+ def test_if_body
+ assert_equal(
+ ["test"],
+ visit(%({% if 1 == 1 %}{{ test }}{% endif %}))
+ )
+ end
+
+ def test_unless_condition
+ assert_equal(
+ ["test"],
+ visit(%({% unless test %}{% endunless %}))
+ )
+ end
+
+ def test_complex_unless_condition
+ assert_equal(
+ ["test"],
+ visit(%({% unless 1 == 1 and 2 == test %}{% endunless %}))
+ )
+ end
+
+ def test_unless_body
+ assert_equal(
+ ["test"],
+ visit(%({% unless 1 == 1 %}{{ test }}{% endunless %}))
+ )
+ end
+
+ def test_elsif_condition
+ assert_equal(
+ ["test"],
+ visit(%({% if 1 == 1 %}{% elsif test %}{% endif %}))
+ )
+ end
+
+ def test_complex_elsif_condition
+ assert_equal(
+ ["test"],
+ visit(%({% if 1 == 1 %}{% elsif 1 == 1 and 2 == test %}{% endif %}))
+ )
+ end
+
+ def test_elsif_body
+ assert_equal(
+ ["test"],
+ visit(%({% if 1 == 1 %}{% elsif 2 == 2 %}{{ test }}{% endif %}))
+ )
+ end
+
+ def test_else_body
+ assert_equal(
+ ["test"],
+ visit(%({% if 1 == 1 %}{% else %}{{ test }}{% endif %}))
+ )
+ end
+
+ def test_case_left
+ assert_equal(
+ ["test"],
+ visit(%({% case test %}{% endcase %}))
+ )
+ end
+
+ def test_case_condition
+ assert_equal(
+ ["test"],
+ visit(%({% case 1 %}{% when test %}{% endcase %}))
+ )
+ end
+
+ def test_case_when_body
+ assert_equal(
+ ["test"],
+ visit(%({% case 1 %}{% when 2 %}{{ test }}{% endcase %}))
+ )
+ end
+
+ def test_case_else_body
+ assert_equal(
+ ["test"],
+ visit(%({% case 1 %}{% else %}{{ test }}{% endcase %}))
+ )
+ end
+
+ def test_for_in
+ assert_equal(
+ ["test"],
+ visit(%({% for x in test %}{% endfor %}))
+ )
+ end
+
+ def test_for_limit
+ assert_equal(
+ ["test"],
+ visit(%({% for x in (1..5) limit: test %}{% endfor %}))
+ )
+ end
+
+ def test_for_offset
+ assert_equal(
+ ["test"],
+ visit(%({% for x in (1..5) offset: test %}{% endfor %}))
+ )
+ end
+
+ def test_for_body
+ assert_equal(
+ ["test"],
+ visit(%({% for x in (1..5) %}{{ test }}{% endfor %}))
+ )
+ end
+
+ def test_tablerow_in
+ assert_equal(
+ ["test"],
+ visit(%({% tablerow x in test %}{% endtablerow %}))
+ )
+ end
+
+ def test_tablerow_limit
+ assert_equal(
+ ["test"],
+ visit(%({% tablerow x in (1..5) limit: test %}{% endtablerow %}))
+ )
+ end
+
+ def test_tablerow_offset
+ assert_equal(
+ ["test"],
+ visit(%({% tablerow x in (1..5) offset: test %}{% endtablerow %}))
+ )
+ end
+
+ def test_tablerow_body
+ assert_equal(
+ ["test"],
+ visit(%({% tablerow x in (1..5) %}{{ test }}{% endtablerow %}))
+ )
+ end
+
+ def test_cycle
+ assert_equal(
+ ["test"],
+ visit(%({% cycle test %}))
+ )
+ end
+
+ def test_assign
+ assert_equal(
+ ["test"],
+ visit(%({% assign x = test %}))
+ )
+ end
+
+ def test_capture
+ assert_equal(
+ ["test"],
+ visit(%({% capture x %}{{ test }}{% endcapture %}))
+ )
+ end
+
+ def test_include
+ assert_equal(
+ ["test"],
+ visit(%({% include test %}))
+ )
+ end
+
+ def test_include_with
+ assert_equal(
+ ["test"],
+ visit(%({% include "hai" with test %}))
+ )
+ end
+
+ def test_include_for
+ assert_equal(
+ ["test"],
+ visit(%({% include "hai" for test %}))
+ )
+ end
+
+ def test_preserve_tree_structure
+ assert_equal(
+ [[nil, [
+ [nil, [[nil, [["other", []]]]]],
+ ["test", []],
+ ["xs", []]
+ ]]],
+ traversal(%({% for x in xs offset: test %}{{ other }}{% endfor %})).visit
+ )
+ end
+
+ private
+
+ def traversal(template)
+ ParseTreeVisitor
+ .for(Template.parse(template).root)
+ .add_callback_for(VariableLookup) { |node| node.name } # rubocop:disable Style/SymbolProc
+ end
+
+ def visit(template)
+ traversal(template).visit.flatten.compact
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/parsing_quirks_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/parsing_quirks_test.rb
new file mode 100644
index 0000000..29cb6d6
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/parsing_quirks_test.rb
@@ -0,0 +1,122 @@
+require 'test_helper'
+
+class ParsingQuirksTest < Minitest::Test
+ include Liquid
+
+ def test_parsing_css
+ text = " div { font-weight: bold; } "
+ assert_equal text, Template.parse(text).render!
+ end
+
+ def test_raise_on_single_close_bracet
+ assert_raises(SyntaxError) do
+ Template.parse("text {{method} oh nos!")
+ end
+ end
+
+ def test_raise_on_label_and_no_close_bracets
+ assert_raises(SyntaxError) do
+ Template.parse("TEST {{ ")
+ end
+ end
+
+ def test_raise_on_label_and_no_close_bracets_percent
+ assert_raises(SyntaxError) do
+ Template.parse("TEST {% ")
+ end
+ end
+
+ def test_error_on_empty_filter
+ assert Template.parse("{{test}}")
+
+ with_error_mode(:lax) do
+ assert Template.parse("{{|test}}")
+ end
+
+ with_error_mode(:strict) do
+ assert_raises(SyntaxError) { Template.parse("{{|test}}") }
+ assert_raises(SyntaxError) { Template.parse("{{test |a|b|}}") }
+ end
+ end
+
+ def test_meaningless_parens_error
+ with_error_mode(:strict) do
+ assert_raises(SyntaxError) do
+ markup = "a == 'foo' or (b == 'bar' and c == 'baz') or false"
+ Template.parse("{% if #{markup} %} YES {% endif %}")
+ end
+ end
+ end
+
+ def test_unexpected_characters_syntax_error
+ with_error_mode(:strict) do
+ assert_raises(SyntaxError) do
+ markup = "true && false"
+ Template.parse("{% if #{markup} %} YES {% endif %}")
+ end
+ assert_raises(SyntaxError) do
+ markup = "false || true"
+ Template.parse("{% if #{markup} %} YES {% endif %}")
+ end
+ end
+ end
+
+ def test_no_error_on_lax_empty_filter
+ assert Template.parse("{{test |a|b|}}", error_mode: :lax)
+ assert Template.parse("{{test}}", error_mode: :lax)
+ assert Template.parse("{{|test|}}", error_mode: :lax)
+ end
+
+ def test_meaningless_parens_lax
+ with_error_mode(:lax) do
+ assigns = { 'b' => 'bar', 'c' => 'baz' }
+ markup = "a == 'foo' or (b == 'bar' and c == 'baz') or false"
+ assert_template_result(' YES ', "{% if #{markup} %} YES {% endif %}", assigns)
+ end
+ end
+
+ def test_unexpected_characters_silently_eat_logic_lax
+ with_error_mode(:lax) do
+ markup = "true && false"
+ assert_template_result(' YES ', "{% if #{markup} %} YES {% endif %}")
+ markup = "false || true"
+ assert_template_result('', "{% if #{markup} %} YES {% endif %}")
+ end
+ end
+
+ def test_raise_on_invalid_tag_delimiter
+ assert_raises(Liquid::SyntaxError) do
+ Template.new.parse('{% end %}')
+ end
+ end
+
+ def test_unanchored_filter_arguments
+ with_error_mode(:lax) do
+ assert_template_result('hi', "{{ 'hi there' | split$$$:' ' | first }}")
+
+ assert_template_result('x', "{{ 'X' | downcase) }}")
+
+ # After the messed up quotes a filter without parameters (reverse) should work
+ # but one with parameters (remove) shouldn't be detected.
+ assert_template_result('here', "{{ 'hi there' | split:\"t\"\" | reverse | first}}")
+ assert_template_result('hi ', "{{ 'hi there' | split:\"t\"\" | remove:\"i\" | first}}")
+ end
+ end
+
+ def test_invalid_variables_work
+ with_error_mode(:lax) do
+ assert_template_result('bar', "{% assign 123foo = 'bar' %}{{ 123foo }}")
+ assert_template_result('123', "{% assign 123 = 'bar' %}{{ 123 }}")
+ end
+ end
+
+ def test_extra_dots_in_ranges
+ with_error_mode(:lax) do
+ assert_template_result('12345', "{% for i in (1...5) %}{{ i }}{% endfor %}")
+ end
+ end
+
+ def test_contains_in_id
+ assert_template_result(' YES ', '{% if containsallshipments == true %} YES {% endif %}', 'containsallshipments' => true)
+ end
+end # ParsingQuirksTest
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/render_profiling_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/render_profiling_test.rb
new file mode 100644
index 0000000..d0111e7
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/render_profiling_test.rb
@@ -0,0 +1,154 @@
+require 'test_helper'
+
+class RenderProfilingTest < Minitest::Test
+ include Liquid
+
+ class ProfilingFileSystem
+ def read_template_file(template_path)
+ "Rendering template {% assign template_name = '#{template_path}'%}\n{{ template_name }}"
+ end
+ end
+
+ def setup
+ Liquid::Template.file_system = ProfilingFileSystem.new
+ end
+
+ def test_template_allows_flagging_profiling
+ t = Template.parse("{{ 'a string' | upcase }}")
+ t.render!
+
+ assert_nil t.profiler
+ end
+
+ def test_parse_makes_available_simple_profiling
+ t = Template.parse("{{ 'a string' | upcase }}", profile: true)
+ t.render!
+
+ assert_equal 1, t.profiler.length
+
+ node = t.profiler[0]
+ assert_equal " 'a string' | upcase ", node.code
+ end
+
+ def test_render_ignores_raw_strings_when_profiling
+ t = Template.parse("This is raw string\nstuff\nNewline", profile: true)
+ t.render!
+
+ assert_equal 0, t.profiler.length
+ end
+
+ def test_profiling_includes_line_numbers_of_liquid_nodes
+ t = Template.parse("{{ 'a string' | upcase }}\n{% increment test %}", profile: true)
+ t.render!
+ assert_equal 2, t.profiler.length
+
+ # {{ 'a string' | upcase }}
+ assert_equal 1, t.profiler[0].line_number
+ # {{ increment test }}
+ assert_equal 2, t.profiler[1].line_number
+ end
+
+ def test_profiling_includes_line_numbers_of_included_partials
+ t = Template.parse("{% include 'a_template' %}", profile: true)
+ t.render!
+
+ included_children = t.profiler[0].children
+
+ # {% assign template_name = 'a_template' %}
+ assert_equal 1, included_children[0].line_number
+ # {{ template_name }}
+ assert_equal 2, included_children[1].line_number
+ end
+
+ def test_profiling_times_the_rendering_of_tokens
+ t = Template.parse("{% include 'a_template' %}", profile: true)
+ t.render!
+
+ node = t.profiler[0]
+ refute_nil node.render_time
+ end
+
+ def test_profiling_times_the_entire_render
+ t = Template.parse("{% include 'a_template' %}", profile: true)
+ t.render!
+
+ assert t.profiler.total_render_time >= 0, "Total render time was not calculated"
+ end
+
+ def test_profiling_uses_include_to_mark_children
+ t = Template.parse("{{ 'a string' | upcase }}\n{% include 'a_template' %}", profile: true)
+ t.render!
+
+ include_node = t.profiler[1]
+ assert_equal 2, include_node.children.length
+ end
+
+ def test_profiling_marks_children_with_the_name_of_included_partial
+ t = Template.parse("{{ 'a string' | upcase }}\n{% include 'a_template' %}", profile: true)
+ t.render!
+
+ include_node = t.profiler[1]
+ include_node.children.each do |child|
+ assert_equal "a_template", child.partial
+ end
+ end
+
+ def test_profiling_supports_multiple_templates
+ t = Template.parse("{{ 'a string' | upcase }}\n{% include 'a_template' %}\n{% include 'b_template' %}", profile: true)
+ t.render!
+
+ a_template = t.profiler[1]
+ a_template.children.each do |child|
+ assert_equal "a_template", child.partial
+ end
+
+ b_template = t.profiler[2]
+ b_template.children.each do |child|
+ assert_equal "b_template", child.partial
+ end
+ end
+
+ def test_profiling_supports_rendering_the_same_partial_multiple_times
+ t = Template.parse("{{ 'a string' | upcase }}\n{% include 'a_template' %}\n{% include 'a_template' %}", profile: true)
+ t.render!
+
+ a_template1 = t.profiler[1]
+ a_template1.children.each do |child|
+ assert_equal "a_template", child.partial
+ end
+
+ a_template2 = t.profiler[2]
+ a_template2.children.each do |child|
+ assert_equal "a_template", child.partial
+ end
+ end
+
+ def test_can_iterate_over_each_profiling_entry
+ t = Template.parse("{{ 'a string' | upcase }}\n{% increment test %}", profile: true)
+ t.render!
+
+ timing_count = 0
+ t.profiler.each do |timing|
+ timing_count += 1
+ end
+
+ assert_equal 2, timing_count
+ end
+
+ def test_profiling_marks_children_of_if_blocks
+ t = Template.parse("{% if true %} {% increment test %} {{ test }} {% endif %}", profile: true)
+ t.render!
+
+ assert_equal 1, t.profiler.length
+ assert_equal 2, t.profiler[0].children.length
+ end
+
+ def test_profiling_marks_children_of_for_blocks
+ t = Template.parse("{% for item in collection %} {{ item }} {% endfor %}", profile: true)
+ t.render!({ "collection" => ["one", "two"] })
+
+ assert_equal 1, t.profiler.length
+ # Will profile each invocation of the for block
+ assert_equal 2, t.profiler[0].children.length
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/security_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/security_test.rb
new file mode 100644
index 0000000..f603ff0
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/security_test.rb
@@ -0,0 +1,80 @@
+require 'test_helper'
+
+module SecurityFilter
+ def add_one(input)
+ "#{input} + 1"
+ end
+end
+
+class SecurityTest < Minitest::Test
+ include Liquid
+
+ def setup
+ @assigns = {}
+ end
+
+ def test_no_instance_eval
+ text = %( {{ '1+1' | instance_eval }} )
+ expected = %( 1+1 )
+
+ assert_equal expected, Template.parse(text).render!(@assigns)
+ end
+
+ def test_no_existing_instance_eval
+ text = %( {{ '1+1' | __instance_eval__ }} )
+ expected = %( 1+1 )
+
+ assert_equal expected, Template.parse(text).render!(@assigns)
+ end
+
+ def test_no_instance_eval_after_mixing_in_new_filter
+ text = %( {{ '1+1' | instance_eval }} )
+ expected = %( 1+1 )
+
+ assert_equal expected, Template.parse(text).render!(@assigns)
+ end
+
+ def test_no_instance_eval_later_in_chain
+ text = %( {{ '1+1' | add_one | instance_eval }} )
+ expected = %( 1+1 + 1 )
+
+ assert_equal expected, Template.parse(text).render!(@assigns, filters: SecurityFilter)
+ end
+
+ def test_does_not_add_filters_to_symbol_table
+ current_symbols = Symbol.all_symbols
+
+ test = %( {{ "some_string" | a_bad_filter }} )
+
+ template = Template.parse(test)
+ assert_equal [], (Symbol.all_symbols - current_symbols)
+
+ template.render!
+ assert_equal [], (Symbol.all_symbols - current_symbols)
+ end
+
+ def test_does_not_add_drop_methods_to_symbol_table
+ current_symbols = Symbol.all_symbols
+
+ assigns = { 'drop' => Drop.new }
+ assert_equal "", Template.parse("{{ drop.custom_method_1 }}", assigns).render!
+ assert_equal "", Template.parse("{{ drop.custom_method_2 }}", assigns).render!
+ assert_equal "", Template.parse("{{ drop.custom_method_3 }}", assigns).render!
+
+ assert_equal [], (Symbol.all_symbols - current_symbols)
+ end
+
+ def test_max_depth_nested_blocks_does_not_raise_exception
+ depth = Liquid::Block::MAX_DEPTH
+ code = "{% if true %}" * depth + "rendered" + "{% endif %}" * depth
+ assert_equal "rendered", Template.parse(code).render!
+ end
+
+ def test_more_than_max_depth_nested_blocks_raises_exception
+ depth = Liquid::Block::MAX_DEPTH + 1
+ code = "{% if true %}" * depth + "rendered" + "{% endif %}" * depth
+ assert_raises(Liquid::StackLevelError) do
+ Template.parse(code).render!
+ end
+ end
+end # SecurityTest
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/standard_filter_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/standard_filter_test.rb
new file mode 100644
index 0000000..6090951
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/standard_filter_test.rb
@@ -0,0 +1,776 @@
+# encoding: utf-8
+
+require 'test_helper'
+
+class Filters
+ include Liquid::StandardFilters
+end
+
+class TestThing
+ attr_reader :foo
+
+ def initialize
+ @foo = 0
+ end
+
+ def to_s
+ "woot: #{@foo}"
+ end
+
+ def [](whatever)
+ to_s
+ end
+
+ def to_liquid
+ @foo += 1
+ self
+ end
+end
+
+class TestDrop < Liquid::Drop
+ def test
+ "testfoo"
+ end
+end
+
+class TestEnumerable < Liquid::Drop
+ include Enumerable
+
+ def each(&block)
+ [ { "foo" => 1, "bar" => 2 }, { "foo" => 2, "bar" => 1 }, { "foo" => 3, "bar" => 3 } ].each(&block)
+ end
+end
+
+class NumberLikeThing < Liquid::Drop
+ def initialize(amount)
+ @amount = amount
+ end
+
+ def to_number
+ @amount
+ end
+end
+
+class StandardFiltersTest < Minitest::Test
+ include Liquid
+
+ def setup
+ @filters = Filters.new
+ end
+
+ def test_size
+ assert_equal 3, @filters.size([1, 2, 3])
+ assert_equal 0, @filters.size([])
+ assert_equal 0, @filters.size(nil)
+ end
+
+ def test_downcase
+ assert_equal 'testing', @filters.downcase("Testing")
+ assert_equal '', @filters.downcase(nil)
+ end
+
+ def test_upcase
+ assert_equal 'TESTING', @filters.upcase("Testing")
+ assert_equal '', @filters.upcase(nil)
+ end
+
+ def test_slice
+ assert_equal 'oob', @filters.slice('foobar', 1, 3)
+ assert_equal 'oobar', @filters.slice('foobar', 1, 1000)
+ assert_equal '', @filters.slice('foobar', 1, 0)
+ assert_equal 'o', @filters.slice('foobar', 1, 1)
+ assert_equal 'bar', @filters.slice('foobar', 3, 3)
+ assert_equal 'ar', @filters.slice('foobar', -2, 2)
+ assert_equal 'ar', @filters.slice('foobar', -2, 1000)
+ assert_equal 'r', @filters.slice('foobar', -1)
+ assert_equal '', @filters.slice(nil, 0)
+ assert_equal '', @filters.slice('foobar', 100, 10)
+ assert_equal '', @filters.slice('foobar', -100, 10)
+ assert_equal 'oob', @filters.slice('foobar', '1', '3')
+ assert_raises(Liquid::ArgumentError) do
+ @filters.slice('foobar', nil)
+ end
+ assert_raises(Liquid::ArgumentError) do
+ @filters.slice('foobar', 0, "")
+ end
+ end
+
+ def test_slice_on_arrays
+ input = 'foobar'.split(//)
+ assert_equal %w(o o b), @filters.slice(input, 1, 3)
+ assert_equal %w(o o b a r), @filters.slice(input, 1, 1000)
+ assert_equal %w(), @filters.slice(input, 1, 0)
+ assert_equal %w(o), @filters.slice(input, 1, 1)
+ assert_equal %w(b a r), @filters.slice(input, 3, 3)
+ assert_equal %w(a r), @filters.slice(input, -2, 2)
+ assert_equal %w(a r), @filters.slice(input, -2, 1000)
+ assert_equal %w(r), @filters.slice(input, -1)
+ assert_equal %w(), @filters.slice(input, 100, 10)
+ assert_equal %w(), @filters.slice(input, -100, 10)
+ end
+
+ def test_truncate
+ assert_equal '1234...', @filters.truncate('1234567890', 7)
+ assert_equal '1234567890', @filters.truncate('1234567890', 20)
+ assert_equal '...', @filters.truncate('1234567890', 0)
+ assert_equal '1234567890', @filters.truncate('1234567890')
+ assert_equal "测试...", @filters.truncate("测试测试测试测试", 5)
+ assert_equal '12341', @filters.truncate("1234567890", 5, 1)
+ end
+
+ def test_split
+ assert_equal ['12', '34'], @filters.split('12~34', '~')
+ assert_equal ['A? ', ' ,Z'], @filters.split('A? ~ ~ ~ ,Z', '~ ~ ~')
+ assert_equal ['A?Z'], @filters.split('A?Z', '~')
+ assert_equal [], @filters.split(nil, ' ')
+ assert_equal ['A', 'Z'], @filters.split('A1Z', 1)
+ end
+
+ def test_escape
+ assert_equal '&lt;strong&gt;', @filters.escape('<strong>')
+ assert_equal '1', @filters.escape(1)
+ assert_equal '2001-02-03', @filters.escape(Date.new(2001, 2, 3))
+ assert_nil @filters.escape(nil)
+ end
+
+ def test_h
+ assert_equal '&lt;strong&gt;', @filters.h('<strong>')
+ assert_equal '1', @filters.h(1)
+ assert_equal '2001-02-03', @filters.h(Date.new(2001, 2, 3))
+ assert_nil @filters.h(nil)
+ end
+
+ def test_escape_once
+ assert_equal '&lt;strong&gt;Hulk&lt;/strong&gt;', @filters.escape_once('&lt;strong&gt;Hulk</strong>')
+ end
+
+ def test_url_encode
+ assert_equal 'foo%2B1%40example.com', @filters.url_encode('foo+1@example.com')
+ assert_equal '1', @filters.url_encode(1)
+ assert_equal '2001-02-03', @filters.url_encode(Date.new(2001, 2, 3))
+ assert_nil @filters.url_encode(nil)
+ end
+
+ def test_url_decode
+ assert_equal 'foo bar', @filters.url_decode('foo+bar')
+ assert_equal 'foo bar', @filters.url_decode('foo%20bar')
+ assert_equal 'foo+1@example.com', @filters.url_decode('foo%2B1%40example.com')
+ assert_equal '1', @filters.url_decode(1)
+ assert_equal '2001-02-03', @filters.url_decode(Date.new(2001, 2, 3))
+ assert_nil @filters.url_decode(nil)
+ exception = assert_raises Liquid::ArgumentError do
+ @filters.url_decode('%ff')
+ end
+ assert_equal 'Liquid error: invalid byte sequence in UTF-8', exception.message
+ end
+
+ def test_truncatewords
+ assert_equal 'one two three', @filters.truncatewords('one two three', 4)
+ assert_equal 'one two...', @filters.truncatewords('one two three', 2)
+ assert_equal 'one two three', @filters.truncatewords('one two three')
+ assert_equal 'Two small (13&#8221; x 5.5&#8221; x 10&#8221; high) baskets fit inside one large basket (13&#8221;...', @filters.truncatewords('Two small (13&#8221; x 5.5&#8221; x 10&#8221; high) baskets fit inside one large basket (13&#8221; x 16&#8221; x 10.5&#8221; high) with cover.', 15)
+ assert_equal "测试测试测试测试", @filters.truncatewords('测试测试测试测试', 5)
+ assert_equal 'one two1', @filters.truncatewords("one two three", 2, 1)
+ end
+
+ def test_strip_html
+ assert_equal 'test', @filters.strip_html("<div>test</div>")
+ assert_equal 'test', @filters.strip_html("<div id='test'>test</div>")
+ assert_equal '', @filters.strip_html("<script type='text/javascript'>document.write('some stuff');</script>")
+ assert_equal '', @filters.strip_html("<style type='text/css'>foo bar</style>")
+ assert_equal 'test', @filters.strip_html("<div\nclass='multiline'>test</div>")
+ assert_equal 'test', @filters.strip_html("<!-- foo bar \n test -->test")
+ assert_equal '', @filters.strip_html(nil)
+
+ # Quirk of the existing implementation
+ assert_equal 'foo;', @filters.strip_html("<<<script </script>script>foo;</script>")
+ end
+
+ def test_join
+ assert_equal '1 2 3 4', @filters.join([1, 2, 3, 4])
+ assert_equal '1 - 2 - 3 - 4', @filters.join([1, 2, 3, 4], ' - ')
+ assert_equal '1121314', @filters.join([1, 2, 3, 4], 1)
+ end
+
+ def test_sort
+ assert_equal [1, 2, 3, 4], @filters.sort([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")
+ 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")
+ end
+
+ def test_sort_when_property_is_sometimes_missing_puts_nils_last
+ input = [
+ { "price" => 4, "handle" => "alpha" },
+ { "handle" => "beta" },
+ { "price" => 1, "handle" => "gamma" },
+ { "handle" => "delta" },
+ { "price" => 2, "handle" => "epsilon" }
+ ]
+ expectation = [
+ { "price" => 1, "handle" => "gamma" },
+ { "price" => 2, "handle" => "epsilon" },
+ { "price" => 4, "handle" => "alpha" },
+ { "handle" => "delta" },
+ { "handle" => "beta" }
+ ]
+ assert_equal expectation, @filters.sort(input, "price")
+ end
+
+ def test_sort_natural
+ assert_equal ["a", "B", "c", "D"], @filters.sort_natural(["c", "D", "a", "B"])
+ assert_equal [{ "a" => "a" }, { "a" => "B" }, { "a" => "c" }, { "a" => "D" }], @filters.sort_natural([{ "a" => "D" }, { "a" => "c" }, { "a" => "a" }, { "a" => "B" }], "a")
+ end
+
+ def test_sort_natural_with_nils
+ assert_equal ["a", "B", "c", "D", nil], @filters.sort_natural([nil, "c", "D", "a", "B"])
+ assert_equal [{ "a" => "a" }, { "a" => "B" }, { "a" => "c" }, { "a" => "D" }, {}], @filters.sort_natural([{ "a" => "D" }, { "a" => "c" }, {}, { "a" => "a" }, { "a" => "B" }], "a")
+ end
+
+ def test_sort_natural_when_property_is_sometimes_missing_puts_nils_last
+ input = [
+ { "price" => "4", "handle" => "alpha" },
+ { "handle" => "beta" },
+ { "price" => "1", "handle" => "gamma" },
+ { "handle" => "delta" },
+ { "price" => 2, "handle" => "epsilon" }
+ ]
+ expectation = [
+ { "price" => "1", "handle" => "gamma" },
+ { "price" => 2, "handle" => "epsilon" },
+ { "price" => "4", "handle" => "alpha" },
+ { "handle" => "delta" },
+ { "handle" => "beta" }
+ ]
+ assert_equal expectation, @filters.sort_natural(input, "price")
+ end
+
+ def test_sort_natural_case_check
+ input = [
+ { "key" => "X" },
+ { "key" => "Y" },
+ { "key" => "Z" },
+ { "fake" => "t" },
+ { "key" => "a" },
+ { "key" => "b" },
+ { "key" => "c" }
+ ]
+ expectation = [
+ { "key" => "a" },
+ { "key" => "b" },
+ { "key" => "c" },
+ { "key" => "X" },
+ { "key" => "Y" },
+ { "key" => "Z" },
+ { "fake" => "t" }
+ ]
+ assert_equal expectation, @filters.sort_natural(input, "key")
+ assert_equal ["a", "b", "c", "X", "Y", "Z"], @filters.sort_natural(["X", "Y", "Z", "a", "b", "c"])
+ end
+
+ def test_sort_empty_array
+ assert_equal [], @filters.sort([], "a")
+ end
+
+ def test_sort_invalid_property
+ foo = [
+ [1],
+ [2],
+ [3]
+ ]
+
+ assert_raises Liquid::ArgumentError do
+ @filters.sort(foo, "bar")
+ end
+ end
+
+ def test_sort_natural_empty_array
+ assert_equal [], @filters.sort_natural([], "a")
+ end
+
+ def test_sort_natural_invalid_property
+ foo = [
+ [1],
+ [2],
+ [3]
+ ]
+
+ assert_raises Liquid::ArgumentError do
+ @filters.sort_natural(foo, "bar")
+ end
+ end
+
+ def test_legacy_sort_hash
+ assert_equal [{ a: 1, b: 2 }], @filters.sort({ a: 1, b: 2 })
+ end
+
+ def test_numerical_vs_lexicographical_sort
+ assert_equal [2, 10], @filters.sort([10, 2])
+ assert_equal [{ "a" => 2 }, { "a" => 10 }], @filters.sort([{ "a" => 10 }, { "a" => 2 }], "a")
+ assert_equal ["10", "2"], @filters.sort(["10", "2"])
+ assert_equal [{ "a" => "10" }, { "a" => "2" }], @filters.sort([{ "a" => "10" }, { "a" => "2" }], "a")
+ end
+
+ def test_uniq
+ assert_equal ["foo"], @filters.uniq("foo")
+ assert_equal [1, 3, 2, 4], @filters.uniq([1, 1, 3, 2, 3, 1, 4, 3, 2, 1])
+ assert_equal [{ "a" => 1 }, { "a" => 3 }, { "a" => 2 }], @filters.uniq([{ "a" => 1 }, { "a" => 3 }, { "a" => 1 }, { "a" => 2 }], "a")
+ testdrop = TestDrop.new
+ assert_equal [testdrop], @filters.uniq([testdrop, TestDrop.new], 'test')
+ end
+
+ def test_uniq_empty_array
+ assert_equal [], @filters.uniq([], "a")
+ end
+
+ def test_uniq_invalid_property
+ foo = [
+ [1],
+ [2],
+ [3]
+ ]
+
+ assert_raises Liquid::ArgumentError do
+ @filters.uniq(foo, "bar")
+ end
+ end
+
+ def test_compact_empty_array
+ assert_equal [], @filters.compact([], "a")
+ end
+
+ def test_compact_invalid_property
+ foo = [
+ [1],
+ [2],
+ [3]
+ ]
+
+ assert_raises Liquid::ArgumentError do
+ @filters.compact(foo, "bar")
+ end
+ end
+
+ def test_reverse
+ assert_equal [4, 3, 2, 1], @filters.reverse([1, 2, 3, 4])
+ end
+
+ def test_legacy_reverse_hash
+ assert_equal [{ a: 1, b: 2 }], @filters.reverse(a: 1, b: 2)
+ end
+
+ def test_map
+ assert_equal [1, 2, 3, 4], @filters.map([{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }], 'a')
+ assert_template_result 'abc', "{{ ary | map:'foo' | map:'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" }}'
+ end
+
+ def test_map_calls_to_liquid
+ t = TestThing.new
+ assert_template_result "woot: 1", '{{ foo | map: "whatever" }}', "foo" => [t]
+ end
+
+ def test_map_on_hashes
+ assert_template_result "4217", '{{ thing | map: "foo" | map: "bar" }}',
+ "thing" => { "foo" => [ { "bar" => 42 }, { "bar" => 17 } ] }
+ end
+
+ def test_legacy_map_on_hashes_with_dynamic_key
+ template = "{% assign key = 'foo' %}{{ thing | map: key | map: 'bar' }}"
+ hash = { "foo" => { "bar" => 42 } }
+ assert_template_result "42", template, "thing" => hash
+ end
+
+ def test_sort_calls_to_liquid
+ t = TestThing.new
+ Liquid::Template.parse('{{ foo | sort: "whatever" }}').render("foo" => [t])
+ assert t.foo > 0
+ end
+
+ def test_map_over_proc
+ drop = TestDrop.new
+ p = proc{ drop }
+ templ = '{{ procs | map: "test" }}'
+ assert_template_result "testfoo", templ, "procs" => [p]
+ end
+
+ def test_map_over_drops_returning_procs
+ drops = [
+ {
+ "proc" => ->{ "foo" },
+ },
+ {
+ "proc" => ->{ "bar" },
+ },
+ ]
+ templ = '{{ drops | map: "proc" }}'
+ assert_template_result "foobar", templ, "drops" => drops
+ end
+
+ def test_map_works_on_enumerables
+ assert_template_result "123", '{{ foo | map: "foo" }}', "foo" => TestEnumerable.new
+ end
+
+ def test_map_returns_empty_on_2d_input_array
+ foo = [
+ [1],
+ [2],
+ [3]
+ ]
+
+ assert_raises Liquid::ArgumentError do
+ @filters.map(foo, "bar")
+ end
+ end
+
+ def test_map_returns_empty_with_no_property
+ foo = [
+ [1],
+ [2],
+ [3]
+ ]
+ assert_raises Liquid::ArgumentError do
+ @filters.map(foo, nil)
+ end
+ end
+
+ def test_sort_works_on_enumerables
+ assert_template_result "213", '{{ foo | sort: "bar" | map: "foo" }}', "foo" => TestEnumerable.new
+ end
+
+ def test_first_and_last_call_to_liquid
+ assert_template_result 'foobar', '{{ foo | first }}', 'foo' => [ThingWithToLiquid.new]
+ assert_template_result 'foobar', '{{ foo | last }}', 'foo' => [ThingWithToLiquid.new]
+ end
+
+ def test_truncate_calls_to_liquid
+ assert_template_result "wo...", '{{ foo | truncate: 5 }}', "foo" => TestThing.new
+ end
+
+ def test_date
+ assert_equal 'May', @filters.date(Time.parse("2006-05-05 10:00:00"), "%B")
+ assert_equal 'June', @filters.date(Time.parse("2006-06-05 10:00:00"), "%B")
+ assert_equal 'July', @filters.date(Time.parse("2006-07-05 10:00:00"), "%B")
+
+ assert_equal 'May', @filters.date("2006-05-05 10:00:00", "%B")
+ assert_equal 'June', @filters.date("2006-06-05 10:00:00", "%B")
+ assert_equal 'July', @filters.date("2006-07-05 10:00:00", "%B")
+
+ assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", "")
+ assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", "")
+ assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", "")
+ assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", nil)
+
+ assert_equal '07/05/2006', @filters.date("2006-07-05 10:00:00", "%m/%d/%Y")
+
+ assert_equal "07/16/2004", @filters.date("Fri Jul 16 01:00:00 2004", "%m/%d/%Y")
+ assert_equal Date.today.year.to_s, @filters.date('now', '%Y')
+ assert_equal Date.today.year.to_s, @filters.date('today', '%Y')
+ assert_equal Date.today.year.to_s, @filters.date('Today', '%Y')
+
+ assert_nil @filters.date(nil, "%B")
+
+ assert_equal '', @filters.date('', "%B")
+
+ with_timezone("UTC") do
+ assert_equal "07/05/2006", @filters.date(1152098955, "%m/%d/%Y")
+ assert_equal "07/05/2006", @filters.date("1152098955", "%m/%d/%Y")
+ end
+ end
+
+ def test_first_last
+ assert_equal 1, @filters.first([1, 2, 3])
+ assert_equal 3, @filters.last([1, 2, 3])
+ assert_nil @filters.first([])
+ assert_nil @filters.last([])
+ end
+
+ def test_replace
+ assert_equal '2 2 2 2', @filters.replace('1 1 1 1', '1', 2)
+ assert_equal '2 2 2 2', @filters.replace('1 1 1 1', 1, 2)
+ assert_equal '2 1 1 1', @filters.replace_first('1 1 1 1', '1', 2)
+ assert_equal '2 1 1 1', @filters.replace_first('1 1 1 1', 1, 2)
+ assert_template_result '2 1 1 1', "{{ '1 1 1 1' | replace_first: '1', 2 }}"
+ end
+
+ def test_remove
+ assert_equal ' ', @filters.remove("a a a a", 'a')
+ assert_equal ' ', @filters.remove("1 1 1 1", 1)
+ assert_equal 'a a a', @filters.remove_first("a a a a", 'a ')
+ assert_equal ' 1 1 1', @filters.remove_first("1 1 1 1", 1)
+ assert_template_result 'a a a', "{{ 'a a a a' | remove_first: 'a ' }}"
+ end
+
+ def test_pipes_in_string_arguments
+ assert_template_result 'foobar', "{{ 'foo|bar' | remove: '|' }}"
+ end
+
+ def test_strip
+ assert_template_result 'ab c', "{{ source | strip }}", 'source' => " ab c "
+ assert_template_result 'ab c', "{{ source | strip }}", 'source' => " \tab c \n \t"
+ end
+
+ def test_lstrip
+ assert_template_result 'ab c ', "{{ source | lstrip }}", 'source' => " ab c "
+ assert_template_result "ab c \n \t", "{{ source | lstrip }}", 'source' => " \tab c \n \t"
+ end
+
+ def test_rstrip
+ assert_template_result " ab c", "{{ source | rstrip }}", 'source' => " ab c "
+ assert_template_result " \tab c", "{{ source | rstrip }}", 'source' => " \tab c \n \t"
+ end
+
+ def test_strip_newlines
+ assert_template_result 'abc', "{{ source | strip_newlines }}", 'source' => "a\nb\nc"
+ assert_template_result 'abc', "{{ source | strip_newlines }}", 'source' => "a\r\nb\nc"
+ end
+
+ def test_newlines_to_br
+ assert_template_result "a<br />\nb<br />\nc", "{{ source | newline_to_br }}", 'source' => "a\nb\nc"
+ end
+
+ def test_plus
+ assert_template_result "2", "{{ 1 | plus:1 }}"
+ assert_template_result "2.0", "{{ '1' | plus:'1.0' }}"
+
+ assert_template_result "5", "{{ price | plus:'2' }}", 'price' => NumberLikeThing.new(3)
+ end
+
+ def test_minus
+ assert_template_result "4", "{{ input | minus:operand }}", 'input' => 5, 'operand' => 1
+ assert_template_result "2.3", "{{ '4.3' | minus:'2' }}"
+
+ assert_template_result "5", "{{ price | minus:'2' }}", 'price' => NumberLikeThing.new(7)
+ end
+
+ def test_abs
+ assert_template_result "17", "{{ 17 | abs }}"
+ assert_template_result "17", "{{ -17 | abs }}"
+ assert_template_result "17", "{{ '17' | abs }}"
+ assert_template_result "17", "{{ '-17' | abs }}"
+ assert_template_result "0", "{{ 0 | abs }}"
+ assert_template_result "0", "{{ '0' | abs }}"
+ assert_template_result "17.42", "{{ 17.42 | abs }}"
+ assert_template_result "17.42", "{{ -17.42 | abs }}"
+ assert_template_result "17.42", "{{ '17.42' | abs }}"
+ assert_template_result "17.42", "{{ '-17.42' | abs }}"
+ end
+
+ def test_times
+ assert_template_result "12", "{{ 3 | times:4 }}"
+ assert_template_result "0", "{{ 'foo' | times:4 }}"
+ assert_template_result "6", "{{ '2.1' | times:3 | replace: '.','-' | plus:0}}"
+ assert_template_result "7.25", "{{ 0.0725 | times:100 }}"
+ assert_template_result "-7.25", '{{ "-0.0725" | times:100 }}'
+ assert_template_result "7.25", '{{ "-0.0725" | times: -100 }}'
+ assert_template_result "4", "{{ price | times:2 }}", 'price' => NumberLikeThing.new(2)
+ end
+
+ def test_divided_by
+ assert_template_result "4", "{{ 12 | divided_by:3 }}"
+ assert_template_result "4", "{{ 14 | divided_by:3 }}"
+
+ assert_template_result "5", "{{ 15 | divided_by:3 }}"
+ assert_equal "Liquid error: divided by 0", Template.parse("{{ 5 | divided_by:0 }}").render
+
+ assert_template_result "0.5", "{{ 2.0 | divided_by:4 }}"
+ assert_raises(Liquid::ZeroDivisionError) do
+ assert_template_result "4", "{{ 1 | modulo: 0 }}"
+ end
+
+ assert_template_result "5", "{{ price | divided_by:2 }}", 'price' => NumberLikeThing.new(10)
+ end
+
+ def test_modulo
+ assert_template_result "1", "{{ 3 | modulo:2 }}"
+ assert_raises(Liquid::ZeroDivisionError) do
+ assert_template_result "4", "{{ 1 | modulo: 0 }}"
+ end
+
+ assert_template_result "1", "{{ price | modulo:2 }}", 'price' => NumberLikeThing.new(3)
+ end
+
+ def test_round
+ assert_template_result "5", "{{ input | round }}", 'input' => 4.6
+ assert_template_result "4", "{{ '4.3' | round }}"
+ assert_template_result "4.56", "{{ input | round: 2 }}", 'input' => 4.5612
+ assert_raises(Liquid::FloatDomainError) do
+ assert_template_result "4", "{{ 1.0 | divided_by: 0.0 | round }}"
+ end
+
+ assert_template_result "5", "{{ price | round }}", 'price' => NumberLikeThing.new(4.6)
+ assert_template_result "4", "{{ price | round }}", 'price' => NumberLikeThing.new(4.3)
+ end
+
+ def test_ceil
+ assert_template_result "5", "{{ input | ceil }}", 'input' => 4.6
+ assert_template_result "5", "{{ '4.3' | ceil }}"
+ assert_raises(Liquid::FloatDomainError) do
+ assert_template_result "4", "{{ 1.0 | divided_by: 0.0 | ceil }}"
+ end
+
+ assert_template_result "5", "{{ price | ceil }}", 'price' => NumberLikeThing.new(4.6)
+ end
+
+ def test_floor
+ assert_template_result "4", "{{ input | floor }}", 'input' => 4.6
+ assert_template_result "4", "{{ '4.3' | floor }}"
+ assert_raises(Liquid::FloatDomainError) do
+ assert_template_result "4", "{{ 1.0 | divided_by: 0.0 | floor }}"
+ end
+
+ assert_template_result "5", "{{ price | floor }}", 'price' => NumberLikeThing.new(5.4)
+ end
+
+ def test_at_most
+ assert_template_result "4", "{{ 5 | at_most:4 }}"
+ assert_template_result "5", "{{ 5 | at_most:5 }}"
+ assert_template_result "5", "{{ 5 | at_most:6 }}"
+
+ assert_template_result "4.5", "{{ 4.5 | at_most:5 }}"
+ assert_template_result "5", "{{ width | at_most:5 }}", 'width' => NumberLikeThing.new(6)
+ assert_template_result "4", "{{ width | at_most:5 }}", 'width' => NumberLikeThing.new(4)
+ assert_template_result "4", "{{ 5 | at_most: width }}", 'width' => NumberLikeThing.new(4)
+ end
+
+ def test_at_least
+ assert_template_result "5", "{{ 5 | at_least:4 }}"
+ assert_template_result "5", "{{ 5 | at_least:5 }}"
+ assert_template_result "6", "{{ 5 | at_least:6 }}"
+
+ assert_template_result "5", "{{ 4.5 | at_least:5 }}"
+ assert_template_result "6", "{{ width | at_least:5 }}", 'width' => NumberLikeThing.new(6)
+ assert_template_result "5", "{{ width | at_least:5 }}", 'width' => NumberLikeThing.new(4)
+ assert_template_result "6", "{{ 5 | at_least: width }}", 'width' => NumberLikeThing.new(6)
+ end
+
+ def test_append
+ assigns = { 'a' => 'bc', 'b' => 'd' }
+ assert_template_result('bcd', "{{ a | append: 'd'}}", assigns)
+ assert_template_result('bcd', "{{ a | append: b}}", assigns)
+ end
+
+ def test_concat
+ assert_equal [1, 2, 3, 4], @filters.concat([1, 2], [3, 4])
+ assert_equal [1, 2, 'a'], @filters.concat([1, 2], ['a'])
+ assert_equal [1, 2, 10], @filters.concat([1, 2], [10])
+
+ assert_raises(Liquid::ArgumentError, "concat filter requires an array argument") do
+ @filters.concat([1, 2], 10)
+ end
+ end
+
+ def test_prepend
+ assigns = { 'a' => 'bc', 'b' => 'a' }
+ assert_template_result('abc', "{{ a | prepend: 'a'}}", assigns)
+ assert_template_result('abc', "{{ a | prepend: b}}", assigns)
+ end
+
+ def test_default
+ assert_equal "foo", @filters.default("foo", "bar")
+ assert_equal "bar", @filters.default(nil, "bar")
+ assert_equal "bar", @filters.default("", "bar")
+ assert_equal "bar", @filters.default(false, "bar")
+ assert_equal "bar", @filters.default([], "bar")
+ assert_equal "bar", @filters.default({}, "bar")
+ end
+
+ def test_cannot_access_private_methods
+ assert_template_result('a', "{{ 'a' | to_number }}")
+ end
+
+ def test_date_raises_nothing
+ assert_template_result('', "{{ '' | date: '%D' }}")
+ assert_template_result('abc', "{{ 'abc' | date: '%D' }}")
+ end
+
+ def test_where
+ 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.where(input, "ok", true)
+ assert_equal expectation, @filters.where(input, "ok")
+ end
+
+ def test_where_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.where(input, "ok", true)
+ assert_equal expectation, @filters.where(input, "ok")
+ end
+
+ def test_where_non_array_map_input
+ assert_equal [{ "a" => "ok" }], @filters.where({ "a" => "ok" }, "a", "ok")
+ assert_equal [], @filters.where({ "a" => "not ok" }, "a", "ok")
+ end
+
+ def test_where_indexable_but_non_map_value
+ assert_raises(Liquid::ArgumentError) { @filters.where(1, "ok", true) }
+ assert_raises(Liquid::ArgumentError) { @filters.where(1, "ok") }
+ end
+
+ def test_where_non_boolean_value
+ input = [
+ { "message" => "Bonjour!", "language" => "French" },
+ { "message" => "Hello!", "language" => "English" },
+ { "message" => "Hallo!", "language" => "German" }
+ ]
+
+ assert_equal [{ "message" => "Bonjour!", "language" => "French" }], @filters.where(input, "language", "French")
+ assert_equal [{ "message" => "Hallo!", "language" => "German" }], @filters.where(input, "language", "German")
+ assert_equal [{ "message" => "Hello!", "language" => "English" }], @filters.where(input, "language", "English")
+ end
+
+ def test_where_array_of_only_unindexable_values
+ assert_nil @filters.where([nil], "ok", true)
+ assert_nil @filters.where([nil], "ok")
+ end
+
+ def test_where_no_target_value
+ input = [
+ { "foo" => false },
+ { "foo" => true },
+ { "foo" => "for sure" },
+ { "bar" => true }
+ ]
+
+ assert_equal [{ "foo" => true }, { "foo" => "for sure" }], @filters.where(input, "foo")
+ end
+
+ private
+
+ def with_timezone(tz)
+ old_tz = ENV['TZ']
+ ENV['TZ'] = tz
+ yield
+ ensure
+ ENV['TZ'] = old_tz
+ end
+end # StandardFiltersTest
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/break_tag_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/break_tag_test.rb
new file mode 100644
index 0000000..0fbde83
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/break_tag_test.rb
@@ -0,0 +1,15 @@
+require 'test_helper'
+
+class BreakTagTest < Minitest::Test
+ include Liquid
+
+ # tests that no weird errors are raised if break is called outside of a
+ # block
+ def test_break_with_no_block
+ assigns = { 'i' => 1 }
+ markup = '{% break %}'
+ expected = ''
+
+ assert_template_result(expected, markup, assigns)
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/continue_tag_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/continue_tag_test.rb
new file mode 100644
index 0000000..ce4c158
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/continue_tag_test.rb
@@ -0,0 +1,15 @@
+require 'test_helper'
+
+class ContinueTagTest < Minitest::Test
+ include Liquid
+
+ # tests that no weird errors are raised if continue is called outside of a
+ # block
+ def test_continue_with_no_block
+ assigns = {}
+ markup = '{% continue %}'
+ expected = ''
+
+ assert_template_result(expected, markup, assigns)
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/for_tag_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/for_tag_test.rb
new file mode 100644
index 0000000..cb7a822
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/for_tag_test.rb
@@ -0,0 +1,410 @@
+require 'test_helper'
+
+class ThingWithValue < Liquid::Drop
+ def value
+ 3
+ end
+end
+
+class ForTagTest < Minitest::Test
+ include Liquid
+
+ def test_for
+ assert_template_result(' yo yo yo yo ', '{%for item in array%} yo {%endfor%}', 'array' => [1, 2, 3, 4])
+ assert_template_result('yoyo', '{%for item in array%}yo{%endfor%}', 'array' => [1, 2])
+ assert_template_result(' yo ', '{%for item in array%} yo {%endfor%}', 'array' => [1])
+ assert_template_result('', '{%for item in array%}{%endfor%}', 'array' => [1, 2])
+ expected = <<HERE
+
+ yo
+
+ yo
+
+ yo
+
+HERE
+ template = <<HERE
+{%for item in array%}
+ yo
+{%endfor%}
+HERE
+ assert_template_result(expected, template, 'array' => [1, 2, 3])
+ end
+
+ def test_for_reversed
+ assigns = { 'array' => [ 1, 2, 3] }
+ assert_template_result('321', '{%for item in array reversed %}{{item}}{%endfor%}', assigns)
+ end
+
+ def test_for_with_range
+ assert_template_result(' 1 2 3 ', '{%for item in (1..3) %} {{item}} {%endfor%}')
+
+ assert_raises(Liquid::ArgumentError) do
+ Template.parse('{% for i in (a..2) %}{% endfor %}').render!("a" => [1, 2])
+ end
+
+ assert_template_result(' 0 1 2 3 ', '{% for item in (a..3) %} {{item}} {% endfor %}', "a" => "invalid integer")
+ end
+
+ def test_for_with_variable_range
+ assert_template_result(' 1 2 3 ', '{%for item in (1..foobar) %} {{item}} {%endfor%}', "foobar" => 3)
+ end
+
+ def test_for_with_hash_value_range
+ foobar = { "value" => 3 }
+ assert_template_result(' 1 2 3 ', '{%for item in (1..foobar.value) %} {{item}} {%endfor%}', "foobar" => foobar)
+ end
+
+ def test_for_with_drop_value_range
+ foobar = ThingWithValue.new
+ assert_template_result(' 1 2 3 ', '{%for item in (1..foobar.value) %} {{item}} {%endfor%}', "foobar" => foobar)
+ end
+
+ def test_for_with_variable
+ assert_template_result(' 1 2 3 ', '{%for item in array%} {{item}} {%endfor%}', 'array' => [1, 2, 3])
+ assert_template_result('123', '{%for item in array%}{{item}}{%endfor%}', 'array' => [1, 2, 3])
+ assert_template_result('123', '{% for item in array %}{{item}}{% endfor %}', 'array' => [1, 2, 3])
+ assert_template_result('abcd', '{%for item in array%}{{item}}{%endfor%}', 'array' => ['a', 'b', 'c', 'd'])
+ assert_template_result('a b c', '{%for item in array%}{{item}}{%endfor%}', 'array' => ['a', ' ', 'b', ' ', 'c'])
+ assert_template_result('abc', '{%for item in array%}{{item}}{%endfor%}', 'array' => ['a', '', 'b', '', 'c'])
+ end
+
+ def test_for_helpers
+ assigns = { 'array' => [1, 2, 3] }
+ assert_template_result(' 1/3 2/3 3/3 ',
+ '{%for item in array%} {{forloop.index}}/{{forloop.length}} {%endfor%}',
+ assigns)
+ assert_template_result(' 1 2 3 ', '{%for item in array%} {{forloop.index}} {%endfor%}', assigns)
+ assert_template_result(' 0 1 2 ', '{%for item in array%} {{forloop.index0}} {%endfor%}', assigns)
+ assert_template_result(' 2 1 0 ', '{%for item in array%} {{forloop.rindex0}} {%endfor%}', assigns)
+ assert_template_result(' 3 2 1 ', '{%for item in array%} {{forloop.rindex}} {%endfor%}', assigns)
+ assert_template_result(' true false false ', '{%for item in array%} {{forloop.first}} {%endfor%}', assigns)
+ assert_template_result(' false false true ', '{%for item in array%} {{forloop.last}} {%endfor%}', assigns)
+ end
+
+ def test_for_and_if
+ assigns = { 'array' => [1, 2, 3] }
+ assert_template_result('+--',
+ '{%for item in array%}{% if forloop.first %}+{% else %}-{% endif %}{%endfor%}',
+ assigns)
+ end
+
+ def test_for_else
+ assert_template_result('+++', '{%for item in array%}+{%else%}-{%endfor%}', 'array' => [1, 2, 3])
+ assert_template_result('-', '{%for item in array%}+{%else%}-{%endfor%}', 'array' => [])
+ assert_template_result('-', '{%for item in array%}+{%else%}-{%endfor%}', 'array' => nil)
+ end
+
+ def test_limiting
+ assigns = { 'array' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] }
+ assert_template_result('12', '{%for i in array limit:2 %}{{ i }}{%endfor%}', assigns)
+ assert_template_result('1234', '{%for i in array limit:4 %}{{ i }}{%endfor%}', assigns)
+ assert_template_result('3456', '{%for i in array limit:4 offset:2 %}{{ i }}{%endfor%}', assigns)
+ assert_template_result('3456', '{%for i in array limit: 4 offset: 2 %}{{ i }}{%endfor%}', assigns)
+ end
+
+ def test_dynamic_variable_limiting
+ assigns = { 'array' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] }
+ assigns['limit'] = 2
+ assigns['offset'] = 2
+
+ assert_template_result('34', '{%for i in array limit: limit offset: offset %}{{ i }}{%endfor%}', assigns)
+ end
+
+ def test_nested_for
+ assigns = { 'array' => [[1, 2], [3, 4], [5, 6]] }
+ assert_template_result('123456', '{%for item in array%}{%for i in item%}{{ i }}{%endfor%}{%endfor%}', assigns)
+ end
+
+ def test_offset_only
+ assigns = { 'array' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] }
+ assert_template_result('890', '{%for i in array offset:7 %}{{ i }}{%endfor%}', assigns)
+ end
+
+ def test_pause_resume
+ assigns = { 'array' => { 'items' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] } }
+ markup = <<-MKUP
+ {%for i in array.items limit: 3 %}{{i}}{%endfor%}
+ next
+ {%for i in array.items offset:continue limit: 3 %}{{i}}{%endfor%}
+ next
+ {%for i in array.items offset:continue limit: 3 %}{{i}}{%endfor%}
+ MKUP
+ expected = <<-XPCTD
+ 123
+ next
+ 456
+ next
+ 789
+ XPCTD
+ assert_template_result(expected, markup, assigns)
+ end
+
+ def test_pause_resume_limit
+ assigns = { 'array' => { 'items' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] } }
+ markup = <<-MKUP
+ {%for i in array.items limit:3 %}{{i}}{%endfor%}
+ next
+ {%for i in array.items offset:continue limit:3 %}{{i}}{%endfor%}
+ next
+ {%for i in array.items offset:continue limit:1 %}{{i}}{%endfor%}
+ MKUP
+ expected = <<-XPCTD
+ 123
+ next
+ 456
+ next
+ 7
+ XPCTD
+ assert_template_result(expected, markup, assigns)
+ end
+
+ def test_pause_resume_big_limit
+ assigns = { 'array' => { 'items' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] } }
+ markup = <<-MKUP
+ {%for i in array.items limit:3 %}{{i}}{%endfor%}
+ next
+ {%for i in array.items offset:continue limit:3 %}{{i}}{%endfor%}
+ next
+ {%for i in array.items offset:continue limit:1000 %}{{i}}{%endfor%}
+ MKUP
+ expected = <<-XPCTD
+ 123
+ next
+ 456
+ next
+ 7890
+ XPCTD
+ assert_template_result(expected, markup, assigns)
+ end
+
+ def test_pause_resume_big_offset
+ assigns = { 'array' => { 'items' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] } }
+ markup = '{%for i in array.items limit:3 %}{{i}}{%endfor%}
+ next
+ {%for i in array.items offset:continue limit:3 %}{{i}}{%endfor%}
+ next
+ {%for i in array.items offset:continue limit:3 offset:1000 %}{{i}}{%endfor%}'
+ expected = '123
+ next
+ 456
+ next
+ '
+ assert_template_result(expected, markup, assigns)
+ end
+
+ def test_for_with_break
+ assigns = { 'array' => { 'items' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] } }
+
+ markup = '{% for i in array.items %}{% break %}{% endfor %}'
+ expected = ""
+ assert_template_result(expected, markup, assigns)
+
+ markup = '{% for i in array.items %}{{ i }}{% break %}{% endfor %}'
+ expected = "1"
+ assert_template_result(expected, markup, assigns)
+
+ markup = '{% for i in array.items %}{% break %}{{ i }}{% endfor %}'
+ expected = ""
+ assert_template_result(expected, markup, assigns)
+
+ markup = '{% for i in array.items %}{{ i }}{% if i > 3 %}{% break %}{% endif %}{% endfor %}'
+ expected = "1234"
+ assert_template_result(expected, markup, assigns)
+
+ # tests to ensure it only breaks out of the local for loop
+ # and not all of them.
+ assigns = { 'array' => [[1, 2], [3, 4], [5, 6]] }
+ markup = '{% for item in array %}' \
+ '{% for i in item %}' \
+ '{% if i == 1 %}' \
+ '{% break %}' \
+ '{% endif %}' \
+ '{{ i }}' \
+ '{% endfor %}' \
+ '{% endfor %}'
+ expected = '3456'
+ assert_template_result(expected, markup, assigns)
+
+ # test break does nothing when unreached
+ assigns = { 'array' => { 'items' => [1, 2, 3, 4, 5] } }
+ markup = '{% for i in array.items %}{% if i == 9999 %}{% break %}{% endif %}{{ i }}{% endfor %}'
+ expected = '12345'
+ assert_template_result(expected, markup, assigns)
+ end
+
+ def test_for_with_continue
+ assigns = { 'array' => { 'items' => [1, 2, 3, 4, 5] } }
+
+ markup = '{% for i in array.items %}{% continue %}{% endfor %}'
+ expected = ""
+ assert_template_result(expected, markup, assigns)
+
+ markup = '{% for i in array.items %}{{ i }}{% continue %}{% endfor %}'
+ expected = "12345"
+ assert_template_result(expected, markup, assigns)
+
+ markup = '{% for i in array.items %}{% continue %}{{ i }}{% endfor %}'
+ expected = ""
+ assert_template_result(expected, markup, assigns)
+
+ markup = '{% for i in array.items %}{% if i > 3 %}{% continue %}{% endif %}{{ i }}{% endfor %}'
+ expected = "123"
+ assert_template_result(expected, markup, assigns)
+
+ markup = '{% for i in array.items %}{% if i == 3 %}{% continue %}{% else %}{{ i }}{% endif %}{% endfor %}'
+ expected = "1245"
+ assert_template_result(expected, markup, assigns)
+
+ # tests to ensure it only continues the local for loop and not all of them.
+ assigns = { 'array' => [[1, 2], [3, 4], [5, 6]] }
+ markup = '{% for item in array %}' \
+ '{% for i in item %}' \
+ '{% if i == 1 %}' \
+ '{% continue %}' \
+ '{% endif %}' \
+ '{{ i }}' \
+ '{% endfor %}' \
+ '{% endfor %}'
+ expected = '23456'
+ assert_template_result(expected, markup, assigns)
+
+ # test continue does nothing when unreached
+ assigns = { 'array' => { 'items' => [1, 2, 3, 4, 5] } }
+ markup = '{% for i in array.items %}{% if i == 9999 %}{% continue %}{% endif %}{{ i }}{% endfor %}'
+ expected = '12345'
+ assert_template_result(expected, markup, assigns)
+ end
+
+ def test_for_tag_string
+ # ruby 1.8.7 "String".each => Enumerator with single "String" element.
+ # ruby 1.9.3 no longer supports .each on String though we mimic
+ # the functionality for backwards compatibility
+
+ assert_template_result('test string',
+ '{%for val in string%}{{val}}{%endfor%}',
+ 'string' => "test string")
+
+ assert_template_result('test string',
+ '{%for val in string limit:1%}{{val}}{%endfor%}',
+ 'string' => "test string")
+
+ assert_template_result('val-string-1-1-0-1-0-true-true-test string',
+ '{%for val in string%}' \
+ '{{forloop.name}}-' \
+ '{{forloop.index}}-' \
+ '{{forloop.length}}-' \
+ '{{forloop.index0}}-' \
+ '{{forloop.rindex}}-' \
+ '{{forloop.rindex0}}-' \
+ '{{forloop.first}}-' \
+ '{{forloop.last}}-' \
+ '{{val}}{%endfor%}',
+ 'string' => "test string")
+ end
+
+ def test_for_parentloop_references_parent_loop
+ assert_template_result('1.1 1.2 1.3 2.1 2.2 2.3 ',
+ '{% for inner in outer %}{% for k in inner %}' \
+ '{{ forloop.parentloop.index }}.{{ forloop.index }} ' \
+ '{% endfor %}{% endfor %}',
+ 'outer' => [[1, 1, 1], [1, 1, 1]])
+ end
+
+ def test_for_parentloop_nil_when_not_present
+ assert_template_result('.1 .2 ',
+ '{% for inner in outer %}' \
+ '{{ forloop.parentloop.index }}.{{ forloop.index }} ' \
+ '{% endfor %}',
+ 'outer' => [[1, 1, 1], [1, 1, 1]])
+ end
+
+ def test_inner_for_over_empty_input
+ assert_template_result 'oo', '{% for a in (1..2) %}o{% for b in empty %}{% endfor %}{% endfor %}'
+ end
+
+ def test_blank_string_not_iterable
+ assert_template_result('', "{% for char in characters %}I WILL NOT BE OUTPUT{% endfor %}", 'characters' => '')
+ end
+
+ def test_bad_variable_naming_in_for_loop
+ assert_raises(Liquid::SyntaxError) do
+ Liquid::Template.parse('{% for a/b in x %}{% endfor %}')
+ end
+ end
+
+ def test_spacing_with_variable_naming_in_for_loop
+ expected = '12345'
+ template = '{% for item in items %}{{item}}{% endfor %}'
+ assigns = { 'items' => [1, 2, 3, 4, 5] }
+ assert_template_result(expected, template, assigns)
+ end
+
+ class LoaderDrop < Liquid::Drop
+ attr_accessor :each_called, :load_slice_called
+
+ def initialize(data)
+ @data = data
+ end
+
+ def each
+ @each_called = true
+ @data.each { |el| yield el }
+ end
+
+ def load_slice(from, to)
+ @load_slice_called = true
+ @data[(from..to - 1)]
+ end
+ end
+
+ def test_iterate_with_each_when_no_limit_applied
+ loader = LoaderDrop.new([1, 2, 3, 4, 5])
+ assigns = { 'items' => loader }
+ expected = '12345'
+ template = '{% for item in items %}{{item}}{% endfor %}'
+ assert_template_result(expected, template, assigns)
+ assert loader.each_called
+ assert !loader.load_slice_called
+ end
+
+ def test_iterate_with_load_slice_when_limit_applied
+ loader = LoaderDrop.new([1, 2, 3, 4, 5])
+ assigns = { 'items' => loader }
+ expected = '1'
+ template = '{% for item in items limit:1 %}{{item}}{% endfor %}'
+ assert_template_result(expected, template, assigns)
+ assert !loader.each_called
+ assert loader.load_slice_called
+ end
+
+ def test_iterate_with_load_slice_when_limit_and_offset_applied
+ loader = LoaderDrop.new([1, 2, 3, 4, 5])
+ assigns = { 'items' => loader }
+ expected = '34'
+ template = '{% for item in items offset:2 limit:2 %}{{item}}{% endfor %}'
+ assert_template_result(expected, template, assigns)
+ assert !loader.each_called
+ assert loader.load_slice_called
+ end
+
+ def test_iterate_with_load_slice_returns_same_results_as_without
+ loader = LoaderDrop.new([1, 2, 3, 4, 5])
+ loader_assigns = { 'items' => loader }
+ array_assigns = { 'items' => [1, 2, 3, 4, 5] }
+ expected = '34'
+ template = '{% for item in items offset:2 limit:2 %}{{item}}{% endfor %}'
+ assert_template_result(expected, template, loader_assigns)
+ assert_template_result(expected, template, array_assigns)
+ end
+
+ def test_for_cleans_up_registers
+ context = Context.new(ErrorDrop.new)
+
+ assert_raises(StandardError) do
+ Liquid::Template.parse('{% for i in (1..2) %}{{ standard_error }}{% endfor %}').render!(context)
+ end
+
+ assert context.registers[:for_stack].empty?
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/if_else_tag_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/if_else_tag_test.rb
new file mode 100644
index 0000000..45a5d3a
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/if_else_tag_test.rb
@@ -0,0 +1,188 @@
+require 'test_helper'
+
+class IfElseTagTest < Minitest::Test
+ include Liquid
+
+ def test_if
+ assert_template_result(' ', ' {% if false %} this text should not go into the output {% endif %} ')
+ assert_template_result(' this text should go into the output ',
+ ' {% if true %} this text should go into the output {% endif %} ')
+ assert_template_result(' you rock ?', '{% if false %} you suck {% endif %} {% if true %} you rock {% endif %}?')
+ end
+
+ def test_literal_comparisons
+ assert_template_result(' NO ', '{% assign v = false %}{% if v %} YES {% else %} NO {% endif %}')
+ assert_template_result(' YES ', '{% assign v = nil %}{% if v == nil %} YES {% else %} NO {% endif %}')
+ end
+
+ def test_if_else
+ assert_template_result(' YES ', '{% if false %} NO {% else %} YES {% endif %}')
+ assert_template_result(' YES ', '{% if true %} YES {% else %} NO {% endif %}')
+ assert_template_result(' YES ', '{% if "foo" %} YES {% else %} NO {% endif %}')
+ end
+
+ def test_if_boolean
+ assert_template_result(' YES ', '{% if var %} YES {% endif %}', 'var' => true)
+ end
+
+ def test_if_or
+ assert_template_result(' YES ', '{% if a or b %} YES {% endif %}', 'a' => true, 'b' => true)
+ assert_template_result(' YES ', '{% if a or b %} YES {% endif %}', 'a' => true, 'b' => false)
+ assert_template_result(' YES ', '{% if a or b %} YES {% endif %}', 'a' => false, 'b' => true)
+ assert_template_result('', '{% if a or b %} YES {% endif %}', 'a' => false, 'b' => false)
+
+ assert_template_result(' YES ', '{% if a or b or c %} YES {% endif %}', 'a' => false, 'b' => false, 'c' => true)
+ assert_template_result('', '{% if a or b or c %} YES {% endif %}', 'a' => false, 'b' => false, 'c' => false)
+ end
+
+ def test_if_or_with_operators
+ assert_template_result(' YES ', '{% if a == true or b == true %} YES {% endif %}', 'a' => true, 'b' => true)
+ assert_template_result(' YES ', '{% if a == true or b == false %} YES {% endif %}', 'a' => true, 'b' => true)
+ assert_template_result('', '{% if a == false or b == false %} YES {% endif %}', 'a' => true, 'b' => true)
+ end
+
+ def test_comparison_of_strings_containing_and_or_or
+ awful_markup = "a == 'and' and b == 'or' and c == 'foo and bar' and d == 'bar or baz' and e == 'foo' and foo and bar"
+ assigns = { 'a' => 'and', 'b' => 'or', 'c' => 'foo and bar', 'd' => 'bar or baz', 'e' => 'foo', 'foo' => true, 'bar' => true }
+ assert_template_result(' YES ', "{% if #{awful_markup} %} YES {% endif %}", assigns)
+ end
+
+ def test_comparison_of_expressions_starting_with_and_or_or
+ assigns = { 'order' => { 'items_count' => 0 }, 'android' => { 'name' => 'Roy' } }
+ assert_template_result("YES",
+ "{% if android.name == 'Roy' %}YES{% endif %}",
+ assigns)
+ assert_template_result("YES",
+ "{% if order.items_count == 0 %}YES{% endif %}",
+ assigns)
+ end
+
+ def test_if_and
+ assert_template_result(' YES ', '{% if true and true %} YES {% endif %}')
+ assert_template_result('', '{% if false and true %} YES {% endif %}')
+ assert_template_result('', '{% if false and true %} YES {% endif %}')
+ end
+
+ def test_hash_miss_generates_false
+ assert_template_result('', '{% if foo.bar %} NO {% endif %}', 'foo' => {})
+ end
+
+ def test_if_from_variable
+ assert_template_result('', '{% if var %} NO {% endif %}', 'var' => false)
+ assert_template_result('', '{% if var %} NO {% endif %}', 'var' => nil)
+ assert_template_result('', '{% if foo.bar %} NO {% endif %}', 'foo' => { 'bar' => false })
+ assert_template_result('', '{% if foo.bar %} NO {% endif %}', 'foo' => {})
+ assert_template_result('', '{% if foo.bar %} NO {% endif %}', 'foo' => nil)
+ assert_template_result('', '{% if foo.bar %} NO {% endif %}', 'foo' => true)
+
+ assert_template_result(' YES ', '{% if var %} YES {% endif %}', 'var' => "text")
+ assert_template_result(' YES ', '{% if var %} YES {% endif %}', 'var' => true)
+ assert_template_result(' YES ', '{% if var %} YES {% endif %}', 'var' => 1)
+ assert_template_result(' YES ', '{% if var %} YES {% endif %}', 'var' => {})
+ assert_template_result(' YES ', '{% if var %} YES {% endif %}', 'var' => [])
+ assert_template_result(' YES ', '{% if "foo" %} YES {% endif %}')
+ assert_template_result(' YES ', '{% if foo.bar %} YES {% endif %}', 'foo' => { 'bar' => true })
+ assert_template_result(' YES ', '{% if foo.bar %} YES {% endif %}', 'foo' => { 'bar' => "text" })
+ assert_template_result(' YES ', '{% if foo.bar %} YES {% endif %}', 'foo' => { 'bar' => 1 })
+ assert_template_result(' YES ', '{% if foo.bar %} YES {% endif %}', 'foo' => { 'bar' => {} })
+ assert_template_result(' YES ', '{% if foo.bar %} YES {% endif %}', 'foo' => { 'bar' => [] })
+
+ assert_template_result(' YES ', '{% if var %} NO {% else %} YES {% endif %}', 'var' => false)
+ assert_template_result(' YES ', '{% if var %} NO {% else %} YES {% endif %}', 'var' => nil)
+ assert_template_result(' YES ', '{% if var %} YES {% else %} NO {% endif %}', 'var' => true)
+ assert_template_result(' YES ', '{% if "foo" %} YES {% else %} NO {% endif %}', 'var' => "text")
+
+ assert_template_result(' YES ', '{% if foo.bar %} NO {% else %} YES {% endif %}', 'foo' => { 'bar' => false })
+ assert_template_result(' YES ', '{% if foo.bar %} YES {% else %} NO {% endif %}', 'foo' => { 'bar' => true })
+ assert_template_result(' YES ', '{% if foo.bar %} YES {% else %} NO {% endif %}', 'foo' => { 'bar' => "text" })
+ assert_template_result(' YES ', '{% if foo.bar %} NO {% else %} YES {% endif %}', 'foo' => { 'notbar' => true })
+ assert_template_result(' YES ', '{% if foo.bar %} NO {% else %} YES {% endif %}', 'foo' => {})
+ assert_template_result(' YES ', '{% if foo.bar %} NO {% else %} YES {% endif %}', 'notfoo' => { 'bar' => true })
+ end
+
+ def test_nested_if
+ assert_template_result('', '{% if false %}{% if false %} NO {% endif %}{% endif %}')
+ assert_template_result('', '{% if false %}{% if true %} NO {% endif %}{% endif %}')
+ assert_template_result('', '{% if true %}{% if false %} NO {% endif %}{% endif %}')
+ assert_template_result(' YES ', '{% if true %}{% if true %} YES {% endif %}{% endif %}')
+
+ assert_template_result(' YES ', '{% if true %}{% if true %} YES {% else %} NO {% endif %}{% else %} NO {% endif %}')
+ assert_template_result(' YES ', '{% if true %}{% if false %} NO {% else %} YES {% endif %}{% else %} NO {% endif %}')
+ assert_template_result(' YES ', '{% if false %}{% if true %} NO {% else %} NONO {% endif %}{% else %} YES {% endif %}')
+ end
+
+ def test_comparisons_on_null
+ assert_template_result('', '{% if null < 10 %} NO {% endif %}')
+ assert_template_result('', '{% if null <= 10 %} NO {% endif %}')
+ assert_template_result('', '{% if null >= 10 %} NO {% endif %}')
+ assert_template_result('', '{% if null > 10 %} NO {% endif %}')
+
+ assert_template_result('', '{% if 10 < null %} NO {% endif %}')
+ assert_template_result('', '{% if 10 <= null %} NO {% endif %}')
+ assert_template_result('', '{% if 10 >= null %} NO {% endif %}')
+ assert_template_result('', '{% if 10 > null %} NO {% endif %}')
+ end
+
+ def test_else_if
+ assert_template_result('0', '{% if 0 == 0 %}0{% elsif 1 == 1%}1{% else %}2{% endif %}')
+ assert_template_result('1', '{% if 0 != 0 %}0{% elsif 1 == 1%}1{% else %}2{% endif %}')
+ assert_template_result('2', '{% if 0 != 0 %}0{% elsif 1 != 1%}1{% else %}2{% endif %}')
+
+ assert_template_result('elsif', '{% if false %}if{% elsif true %}elsif{% endif %}')
+ end
+
+ def test_syntax_error_no_variable
+ assert_raises(SyntaxError){ assert_template_result('', '{% if jerry == 1 %}') }
+ end
+
+ def test_syntax_error_no_expression
+ assert_raises(SyntaxError) { assert_template_result('', '{% if %}') }
+ end
+
+ def test_if_with_custom_condition
+ original_op = Condition.operators['contains']
+ Condition.operators['contains'] = :[]
+
+ assert_template_result('yes', %({% if 'bob' contains 'o' %}yes{% endif %}))
+ assert_template_result('no', %({% if 'bob' contains 'f' %}yes{% else %}no{% endif %}))
+ ensure
+ Condition.operators['contains'] = original_op
+ end
+
+ def test_operators_are_ignored_unless_isolated
+ original_op = Condition.operators['contains']
+ Condition.operators['contains'] = :[]
+
+ assert_template_result('yes',
+ %({% if 'gnomeslab-and-or-liquid' contains 'gnomeslab-and-or-liquid' %}yes{% endif %}))
+ ensure
+ Condition.operators['contains'] = original_op
+ end
+
+ def test_operators_are_whitelisted
+ assert_raises(SyntaxError) do
+ assert_template_result('', %({% if 1 or throw or or 1 %}yes{% endif %}))
+ end
+ end
+
+ def test_multiple_conditions
+ tpl = "{% if a or b and c %}true{% else %}false{% endif %}"
+
+ tests = {
+ [true, true, true] => true,
+ [true, true, false] => true,
+ [true, false, true] => true,
+ [true, false, false] => true,
+ [false, true, true] => true,
+ [false, true, false] => false,
+ [false, false, true] => false,
+ [false, false, false] => false,
+ }
+
+ tests.each do |vals, expected|
+ a, b, c = vals
+ assigns = { 'a' => a, 'b' => b, 'c' => c }
+ assert_template_result expected.to_s, tpl, assigns, assigns.to_s
+ end
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/include_tag_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/include_tag_test.rb
new file mode 100644
index 0000000..9c188d5
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/include_tag_test.rb
@@ -0,0 +1,253 @@
+require 'test_helper'
+
+class TestFileSystem
+ def read_template_file(template_path)
+ case template_path
+ when "product"
+ "Product: {{ product.title }} "
+
+ when "locale_variables"
+ "Locale: {{echo1}} {{echo2}}"
+
+ when "variant"
+ "Variant: {{ variant.title }}"
+
+ when "nested_template"
+ "{% include 'header' %} {% include 'body' %} {% include 'footer' %}"
+
+ when "body"
+ "body {% include 'body_detail' %}"
+
+ when "nested_product_template"
+ "Product: {{ nested_product_template.title }} {%include 'details'%} "
+
+ when "recursively_nested_template"
+ "-{% include 'recursively_nested_template' %}"
+
+ when "pick_a_source"
+ "from TestFileSystem"
+
+ when 'assignments'
+ "{% assign foo = 'bar' %}"
+
+ when 'break'
+ "{% break %}"
+
+ else
+ template_path
+ end
+ end
+end
+
+class OtherFileSystem
+ def read_template_file(template_path)
+ 'from OtherFileSystem'
+ end
+end
+
+class CountingFileSystem
+ attr_reader :count
+ def read_template_file(template_path)
+ @count ||= 0
+ @count += 1
+ 'from CountingFileSystem'
+ end
+end
+
+class CustomInclude < Liquid::Tag
+ Syntax = /(#{Liquid::QuotedFragment}+)(\s+(?:with|for)\s+(#{Liquid::QuotedFragment}+))?/o
+
+ def initialize(tag_name, markup, tokens)
+ markup =~ Syntax
+ @template_name = $1
+ super
+ end
+
+ def parse(tokens)
+ end
+
+ def render(context)
+ @template_name[1..-2]
+ end
+end
+
+class IncludeTagTest < Minitest::Test
+ include Liquid
+
+ def setup
+ Liquid::Template.file_system = TestFileSystem.new
+ end
+
+ def test_include_tag_looks_for_file_system_in_registers_first
+ assert_equal 'from OtherFileSystem',
+ Template.parse("{% include 'pick_a_source' %}").render!({}, registers: { file_system: OtherFileSystem.new })
+ end
+
+ def test_include_tag_with
+ assert_template_result "Product: Draft 151cm ",
+ "{% include 'product' with products[0] %}", "products" => [ { 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' } ]
+ end
+
+ def test_include_tag_with_default_name
+ assert_template_result "Product: Draft 151cm ",
+ "{% include 'product' %}", "product" => { 'title' => 'Draft 151cm' }
+ end
+
+ def test_include_tag_for
+ assert_template_result "Product: Draft 151cm Product: Element 155cm ",
+ "{% include 'product' for products %}", "products" => [ { 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' } ]
+ end
+
+ def test_include_tag_with_local_variables
+ assert_template_result "Locale: test123 ", "{% include 'locale_variables' echo1: 'test123' %}"
+ end
+
+ def test_include_tag_with_multiple_local_variables
+ assert_template_result "Locale: test123 test321",
+ "{% include 'locale_variables' echo1: 'test123', echo2: 'test321' %}"
+ end
+
+ def test_include_tag_with_multiple_local_variables_from_context
+ assert_template_result "Locale: test123 test321",
+ "{% include 'locale_variables' echo1: echo1, echo2: more_echos.echo2 %}",
+ 'echo1' => 'test123', 'more_echos' => { "echo2" => 'test321' }
+ end
+
+ def test_included_templates_assigns_variables
+ assert_template_result "bar", "{% include 'assignments' %}{{ foo }}"
+ end
+
+ def test_nested_include_tag
+ assert_template_result "body body_detail", "{% include 'body' %}"
+
+ assert_template_result "header body body_detail footer", "{% include 'nested_template' %}"
+ end
+
+ def test_nested_include_with_variable
+ assert_template_result "Product: Draft 151cm details ",
+ "{% include 'nested_product_template' with product %}", "product" => { "title" => 'Draft 151cm' }
+
+ assert_template_result "Product: Draft 151cm details Product: Element 155cm details ",
+ "{% include 'nested_product_template' for products %}", "products" => [{ "title" => 'Draft 151cm' }, { "title" => 'Element 155cm' }]
+ end
+
+ def test_recursively_included_template_does_not_produce_endless_loop
+ infinite_file_system = Class.new do
+ def read_template_file(template_path)
+ "-{% include 'loop' %}"
+ end
+ end
+
+ Liquid::Template.file_system = infinite_file_system.new
+
+ assert_raises(Liquid::StackLevelError) do
+ Template.parse("{% include 'loop' %}").render!
+ end
+ end
+
+ def test_dynamically_choosen_template
+ assert_template_result "Test123", "{% include template %}", "template" => 'Test123'
+ assert_template_result "Test321", "{% include template %}", "template" => 'Test321'
+
+ assert_template_result "Product: Draft 151cm ", "{% include template for product %}",
+ "template" => 'product', 'product' => { 'title' => 'Draft 151cm' }
+ end
+
+ def test_include_tag_caches_second_read_of_same_partial
+ file_system = CountingFileSystem.new
+ assert_equal 'from CountingFileSystemfrom CountingFileSystem',
+ Template.parse("{% include 'pick_a_source' %}{% include 'pick_a_source' %}").render!({}, registers: { file_system: file_system })
+ assert_equal 1, file_system.count
+ end
+
+ def test_include_tag_doesnt_cache_partials_across_renders
+ file_system = CountingFileSystem.new
+ assert_equal 'from CountingFileSystem',
+ Template.parse("{% include 'pick_a_source' %}").render!({}, registers: { file_system: file_system })
+ assert_equal 1, file_system.count
+
+ assert_equal 'from CountingFileSystem',
+ Template.parse("{% include 'pick_a_source' %}").render!({}, registers: { file_system: file_system })
+ assert_equal 2, file_system.count
+ end
+
+ def test_include_tag_within_if_statement
+ assert_template_result "foo_if_true", "{% if true %}{% include 'foo_if_true' %}{% endif %}"
+ end
+
+ def test_custom_include_tag
+ original_tag = Liquid::Template.tags['include']
+ Liquid::Template.tags['include'] = CustomInclude
+ begin
+ assert_equal "custom_foo",
+ Template.parse("{% include 'custom_foo' %}").render!
+ ensure
+ Liquid::Template.tags['include'] = original_tag
+ end
+ end
+
+ def test_custom_include_tag_within_if_statement
+ original_tag = Liquid::Template.tags['include']
+ Liquid::Template.tags['include'] = CustomInclude
+ begin
+ assert_equal "custom_foo_if_true",
+ Template.parse("{% if true %}{% include 'custom_foo_if_true' %}{% endif %}").render!
+ ensure
+ Liquid::Template.tags['include'] = original_tag
+ end
+ end
+
+ def test_does_not_add_error_in_strict_mode_for_missing_variable
+ Liquid::Template.file_system = TestFileSystem.new
+
+ a = Liquid::Template.parse(' {% include "nested_template" %}')
+ a.render!
+ assert_empty a.errors
+ end
+
+ def test_passing_options_to_included_templates
+ assert_raises(Liquid::SyntaxError) do
+ Template.parse("{% include template %}", error_mode: :strict).render!("template" => '{{ "X" || downcase }}')
+ end
+ with_error_mode(:lax) do
+ assert_equal 'x', Template.parse("{% include template %}", error_mode: :strict, include_options_blacklist: true).render!("template" => '{{ "X" || downcase }}')
+ end
+ assert_raises(Liquid::SyntaxError) do
+ Template.parse("{% include template %}", error_mode: :strict, include_options_blacklist: [:locale]).render!("template" => '{{ "X" || downcase }}')
+ end
+ with_error_mode(:lax) do
+ assert_equal 'x', Template.parse("{% include template %}", error_mode: :strict, include_options_blacklist: [:error_mode]).render!("template" => '{{ "X" || downcase }}')
+ end
+ end
+
+ def test_render_raise_argument_error_when_template_is_undefined
+ assert_raises(Liquid::ArgumentError) do
+ template = Liquid::Template.parse('{% include undefined_variable %}')
+ template.render!
+ end
+ assert_raises(Liquid::ArgumentError) do
+ template = Liquid::Template.parse('{% include nil %}')
+ template.render!
+ end
+ end
+
+ def test_including_via_variable_value
+ assert_template_result "from TestFileSystem", "{% assign page = 'pick_a_source' %}{% include page %}"
+
+ assert_template_result "Product: Draft 151cm ", "{% assign page = 'product' %}{% include page %}", "product" => { 'title' => 'Draft 151cm' }
+
+ assert_template_result "Product: Draft 151cm ", "{% assign page = 'product' %}{% include page for foo %}", "foo" => { 'title' => 'Draft 151cm' }
+ end
+
+ def test_including_with_strict_variables
+ template = Liquid::Template.parse("{% include 'simple' %}", error_mode: :warn)
+ template.render(nil, strict_variables: true)
+
+ assert_equal [], template.errors
+ end
+
+ def test_break_through_include
+ assert_template_result "1", "{% for i in (1..3) %}{{ i }}{% break %}{{ i }}{% endfor %}"
+ assert_template_result "1", "{% for i in (1..3) %}{{ i }}{% include 'break' %}{{ i }}{% endfor %}"
+ end
+end # IncludeTagTest
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/increment_tag_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/increment_tag_test.rb
new file mode 100644
index 0000000..97c51ac
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/increment_tag_test.rb
@@ -0,0 +1,23 @@
+require 'test_helper'
+
+class IncrementTagTest < Minitest::Test
+ include Liquid
+
+ def test_inc
+ assert_template_result('0', '{%increment port %}', {})
+ assert_template_result('0 1', '{%increment port %} {%increment port%}', {})
+ assert_template_result('0 0 1 2 1',
+ '{%increment port %} {%increment starboard%} ' \
+ '{%increment port %} {%increment port%} ' \
+ '{%increment starboard %}', {})
+ end
+
+ def test_dec
+ assert_template_result('9', '{%decrement port %}', { 'port' => 10 })
+ assert_template_result('-1 -2', '{%decrement port %} {%decrement port%}', {})
+ assert_template_result('1 5 2 2 5',
+ '{%increment port %} {%increment starboard%} ' \
+ '{%increment port %} {%decrement port%} ' \
+ '{%decrement starboard %}', { 'port' => 1, 'starboard' => 5 })
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/raw_tag_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/raw_tag_test.rb
new file mode 100644
index 0000000..634d052
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/raw_tag_test.rb
@@ -0,0 +1,31 @@
+require 'test_helper'
+
+class RawTagTest < Minitest::Test
+ include Liquid
+
+ def test_tag_in_raw
+ assert_template_result '{% comment %} test {% endcomment %}',
+ '{% raw %}{% comment %} test {% endcomment %}{% endraw %}'
+ end
+
+ def test_output_in_raw
+ assert_template_result '{{ test }}', '{% raw %}{{ test }}{% endraw %}'
+ end
+
+ def test_open_tag_in_raw
+ assert_template_result ' Foobar {% invalid ', '{% raw %} Foobar {% invalid {% endraw %}'
+ assert_template_result ' Foobar invalid %} ', '{% raw %} Foobar invalid %} {% endraw %}'
+ assert_template_result ' Foobar {{ invalid ', '{% raw %} Foobar {{ invalid {% endraw %}'
+ assert_template_result ' Foobar invalid }} ', '{% raw %} Foobar invalid }} {% endraw %}'
+ assert_template_result ' Foobar {% invalid {% {% endraw ', '{% raw %} Foobar {% invalid {% {% endraw {% endraw %}'
+ assert_template_result ' Foobar {% {% {% ', '{% raw %} Foobar {% {% {% {% endraw %}'
+ assert_template_result ' test {% raw %} {% endraw %}', '{% raw %} test {% raw %} {% {% endraw %}endraw %}'
+ assert_template_result ' Foobar {{ invalid 1', '{% raw %} Foobar {{ invalid {% endraw %}{{ 1 }}'
+ end
+
+ def test_invalid_raw
+ assert_match_syntax_error(/tag was never closed/, '{% raw %} foo')
+ assert_match_syntax_error(/Valid syntax/, '{% raw } foo {% endraw %}')
+ assert_match_syntax_error(/Valid syntax/, '{% raw } foo %}{% endraw %}')
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/standard_tag_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/standard_tag_test.rb
new file mode 100644
index 0000000..4b4703a
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/standard_tag_test.rb
@@ -0,0 +1,296 @@
+require 'test_helper'
+
+class StandardTagTest < Minitest::Test
+ include Liquid
+
+ def test_no_transform
+ assert_template_result('this text should come out of the template without change...',
+ 'this text should come out of the template without change...')
+
+ assert_template_result('blah', 'blah')
+ assert_template_result('<blah>', '<blah>')
+ assert_template_result('|,.:', '|,.:')
+ assert_template_result('', '')
+
+ text = %(this shouldnt see any transformation either but has multiple lines
+ as you can clearly see here ...)
+ assert_template_result(text, text)
+ end
+
+ def test_has_a_block_which_does_nothing
+ assert_template_result(%(the comment block should be removed .. right?),
+ %(the comment block should be removed {%comment%} be gone.. {%endcomment%} .. right?))
+
+ assert_template_result('', '{%comment%}{%endcomment%}')
+ assert_template_result('', '{%comment%}{% endcomment %}')
+ assert_template_result('', '{% comment %}{%endcomment%}')
+ assert_template_result('', '{% comment %}{% endcomment %}')
+ assert_template_result('', '{%comment%}comment{%endcomment%}')
+ assert_template_result('', '{% comment %}comment{% endcomment %}')
+ assert_template_result('', '{% comment %} 1 {% comment %} 2 {% endcomment %} 3 {% endcomment %}')
+
+ assert_template_result('', '{%comment%}{%blabla%}{%endcomment%}')
+ assert_template_result('', '{% comment %}{% blabla %}{% endcomment %}')
+ assert_template_result('', '{%comment%}{% endif %}{%endcomment%}')
+ assert_template_result('', '{% comment %}{% endwhatever %}{% endcomment %}')
+ assert_template_result('', '{% comment %}{% raw %} {{%%%%}} }} { {% endcomment %} {% comment {% endraw %} {% endcomment %}')
+
+ assert_template_result('foobar', 'foo{%comment%}comment{%endcomment%}bar')
+ assert_template_result('foobar', 'foo{% comment %}comment{% endcomment %}bar')
+ assert_template_result('foobar', 'foo{%comment%} comment {%endcomment%}bar')
+ assert_template_result('foobar', 'foo{% comment %} comment {% endcomment %}bar')
+
+ assert_template_result('foo bar', 'foo {%comment%} {%endcomment%} bar')
+ assert_template_result('foo bar', 'foo {%comment%}comment{%endcomment%} bar')
+ assert_template_result('foo bar', 'foo {%comment%} comment {%endcomment%} bar')
+
+ assert_template_result('foobar', 'foo{%comment%}
+ {%endcomment%}bar')
+ end
+
+ def test_hyphenated_assign
+ assigns = { 'a-b' => '1' }
+ assert_template_result('a-b:1 a-b:2', 'a-b:{{a-b}} {%assign a-b = 2 %}a-b:{{a-b}}', assigns)
+ end
+
+ def test_assign_with_colon_and_spaces
+ assigns = { 'var' => { 'a:b c' => { 'paged' => '1' } } }
+ assert_template_result('var2: 1', '{%assign var2 = var["a:b c"].paged %}var2: {{var2}}', assigns)
+ end
+
+ def test_capture
+ assigns = { 'var' => 'content' }
+ assert_template_result('content foo content foo ',
+ '{{ var2 }}{% capture var2 %}{{ var }} foo {% endcapture %}{{ var2 }}{{ var2 }}',
+ assigns)
+ end
+
+ def test_capture_detects_bad_syntax
+ assert_raises(SyntaxError) do
+ assert_template_result('content foo content foo ',
+ '{{ var2 }}{% capture %}{{ var }} foo {% endcapture %}{{ var2 }}{{ var2 }}',
+ { 'var' => 'content' })
+ end
+ end
+
+ def test_case
+ assigns = { 'condition' => 2 }
+ assert_template_result(' its 2 ',
+ '{% case condition %}{% when 1 %} its 1 {% when 2 %} its 2 {% endcase %}',
+ assigns)
+
+ assigns = { 'condition' => 1 }
+ assert_template_result(' its 1 ',
+ '{% case condition %}{% when 1 %} its 1 {% when 2 %} its 2 {% endcase %}',
+ assigns)
+
+ assigns = { 'condition' => 3 }
+ assert_template_result('',
+ '{% case condition %}{% when 1 %} its 1 {% when 2 %} its 2 {% endcase %}',
+ assigns)
+
+ assigns = { 'condition' => "string here" }
+ assert_template_result(' hit ',
+ '{% case condition %}{% when "string here" %} hit {% endcase %}',
+ assigns)
+
+ assigns = { 'condition' => "bad string here" }
+ assert_template_result('',
+ '{% case condition %}{% when "string here" %} hit {% endcase %}',\
+ assigns)
+ end
+
+ def test_case_with_else
+ assigns = { 'condition' => 5 }
+ assert_template_result(' hit ',
+ '{% case condition %}{% when 5 %} hit {% else %} else {% endcase %}',
+ assigns)
+
+ assigns = { 'condition' => 6 }
+ assert_template_result(' else ',
+ '{% case condition %}{% when 5 %} hit {% else %} else {% endcase %}',
+ assigns)
+
+ assigns = { 'condition' => 6 }
+ assert_template_result(' else ',
+ '{% case condition %} {% when 5 %} hit {% else %} else {% endcase %}',
+ assigns)
+ end
+
+ def test_case_on_size
+ assert_template_result('', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [])
+ assert_template_result('1', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1])
+ assert_template_result('2', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1, 1])
+ assert_template_result('', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1, 1, 1])
+ assert_template_result('', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1, 1, 1, 1])
+ assert_template_result('', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1, 1, 1, 1, 1])
+ end
+
+ def test_case_on_size_with_else
+ assert_template_result('else',
+ '{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}',
+ 'a' => [])
+
+ assert_template_result('1',
+ '{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}',
+ 'a' => [1])
+
+ assert_template_result('2',
+ '{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}',
+ 'a' => [1, 1])
+
+ assert_template_result('else',
+ '{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}',
+ 'a' => [1, 1, 1])
+
+ assert_template_result('else',
+ '{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}',
+ 'a' => [1, 1, 1, 1])
+
+ assert_template_result('else',
+ '{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}',
+ 'a' => [1, 1, 1, 1, 1])
+ end
+
+ def test_case_on_length_with_else
+ assert_template_result('else',
+ '{% case a.empty? %}{% when true %}true{% when false %}false{% else %}else{% endcase %}',
+ {})
+
+ assert_template_result('false',
+ '{% case false %}{% when true %}true{% when false %}false{% else %}else{% endcase %}',
+ {})
+
+ assert_template_result('true',
+ '{% case true %}{% when true %}true{% when false %}false{% else %}else{% endcase %}',
+ {})
+
+ assert_template_result('else',
+ '{% case NULL %}{% when true %}true{% when false %}false{% else %}else{% endcase %}',
+ {})
+ end
+
+ def test_assign_from_case
+ # Example from the shopify forums
+ code = "{% case collection.handle %}{% when 'menswear-jackets' %}{% assign ptitle = 'menswear' %}{% when 'menswear-t-shirts' %}{% assign ptitle = 'menswear' %}{% else %}{% assign ptitle = 'womenswear' %}{% endcase %}{{ ptitle }}"
+ template = Liquid::Template.parse(code)
+ assert_equal "menswear", template.render!("collection" => { 'handle' => 'menswear-jackets' })
+ assert_equal "menswear", template.render!("collection" => { 'handle' => 'menswear-t-shirts' })
+ assert_equal "womenswear", template.render!("collection" => { 'handle' => 'x' })
+ assert_equal "womenswear", template.render!("collection" => { 'handle' => 'y' })
+ assert_equal "womenswear", template.render!("collection" => { 'handle' => 'z' })
+ end
+
+ def test_case_when_or
+ code = '{% case condition %}{% when 1 or 2 or 3 %} its 1 or 2 or 3 {% when 4 %} its 4 {% endcase %}'
+ assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 1 })
+ assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 2 })
+ assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 3 })
+ assert_template_result(' its 4 ', code, { 'condition' => 4 })
+ assert_template_result('', code, { 'condition' => 5 })
+
+ code = '{% case condition %}{% when 1 or "string" or null %} its 1 or 2 or 3 {% when 4 %} its 4 {% endcase %}'
+ assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 1 })
+ assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 'string' })
+ assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => nil })
+ assert_template_result('', code, { 'condition' => 'something else' })
+ end
+
+ def test_case_when_comma
+ code = '{% case condition %}{% when 1, 2, 3 %} its 1 or 2 or 3 {% when 4 %} its 4 {% endcase %}'
+ assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 1 })
+ assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 2 })
+ assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 3 })
+ assert_template_result(' its 4 ', code, { 'condition' => 4 })
+ assert_template_result('', code, { 'condition' => 5 })
+
+ code = '{% case condition %}{% when 1, "string", null %} its 1 or 2 or 3 {% when 4 %} its 4 {% endcase %}'
+ assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 1 })
+ assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => 'string' })
+ assert_template_result(' its 1 or 2 or 3 ', code, { 'condition' => nil })
+ assert_template_result('', code, { 'condition' => 'something else' })
+ end
+
+ def test_assign
+ assert_template_result 'variable', '{% assign a = "variable"%}{{a}}'
+ end
+
+ def test_assign_unassigned
+ assigns = { 'var' => 'content' }
+ assert_template_result('var2: var2:content', 'var2:{{var2}} {%assign var2 = var%} var2:{{var2}}', assigns)
+ end
+
+ def test_assign_an_empty_string
+ assert_template_result '', '{% assign a = ""%}{{a}}'
+ end
+
+ def test_assign_is_global
+ assert_template_result 'variable', '{%for i in (1..2) %}{% assign a = "variable"%}{% endfor %}{{a}}'
+ end
+
+ def test_case_detects_bad_syntax
+ assert_raises(SyntaxError) do
+ assert_template_result('', '{% case false %}{% when %}true{% endcase %}', {})
+ end
+
+ assert_raises(SyntaxError) do
+ assert_template_result('', '{% case false %}{% huh %}true{% endcase %}', {})
+ end
+ end
+
+ def test_cycle
+ assert_template_result('one', '{%cycle "one", "two"%}')
+ assert_template_result('one two', '{%cycle "one", "two"%} {%cycle "one", "two"%}')
+ assert_template_result(' two', '{%cycle "", "two"%} {%cycle "", "two"%}')
+
+ assert_template_result('one two one', '{%cycle "one", "two"%} {%cycle "one", "two"%} {%cycle "one", "two"%}')
+
+ assert_template_result('text-align: left text-align: right',
+ '{%cycle "text-align: left", "text-align: right" %} {%cycle "text-align: left", "text-align: right"%}')
+ end
+
+ def test_multiple_cycles
+ assert_template_result('1 2 1 1 2 3 1',
+ '{%cycle 1,2%} {%cycle 1,2%} {%cycle 1,2%} {%cycle 1,2,3%} {%cycle 1,2,3%} {%cycle 1,2,3%} {%cycle 1,2,3%}')
+ end
+
+ def test_multiple_named_cycles
+ assert_template_result('one one two two one one',
+ '{%cycle 1: "one", "two" %} {%cycle 2: "one", "two" %} {%cycle 1: "one", "two" %} {%cycle 2: "one", "two" %} {%cycle 1: "one", "two" %} {%cycle 2: "one", "two" %}')
+ end
+
+ def test_multiple_named_cycles_with_names_from_context
+ assigns = { "var1" => 1, "var2" => 2 }
+ assert_template_result('one one two two one one',
+ '{%cycle var1: "one", "two" %} {%cycle var2: "one", "two" %} {%cycle var1: "one", "two" %} {%cycle var2: "one", "two" %} {%cycle var1: "one", "two" %} {%cycle var2: "one", "two" %}', assigns)
+ end
+
+ def test_size_of_array
+ assigns = { "array" => [1, 2, 3, 4] }
+ assert_template_result('array has 4 elements', "array has {{ array.size }} elements", assigns)
+ end
+
+ def test_size_of_hash
+ assigns = { "hash" => { a: 1, b: 2, c: 3, d: 4 } }
+ assert_template_result('hash has 4 elements', "hash has {{ hash.size }} elements", assigns)
+ end
+
+ def test_illegal_symbols
+ assert_template_result('', '{% if true == empty %}?{% endif %}', {})
+ assert_template_result('', '{% if true == null %}?{% endif %}', {})
+ assert_template_result('', '{% if empty == true %}?{% endif %}', {})
+ assert_template_result('', '{% if null == true %}?{% endif %}', {})
+ end
+
+ def test_ifchanged
+ assigns = { 'array' => [ 1, 1, 2, 2, 3, 3] }
+ assert_template_result('123', '{%for item in array%}{%ifchanged%}{{item}}{% endifchanged %}{%endfor%}', assigns)
+
+ assigns = { 'array' => [ 1, 1, 1, 1] }
+ assert_template_result('1', '{%for item in array%}{%ifchanged%}{{item}}{% endifchanged %}{%endfor%}', assigns)
+ end
+
+ def test_multiline_tag
+ assert_template_result '0 1 2 3', "0{%\nfor i in (1..3)\n%} {{\ni\n}}{%\nendfor\n%}"
+ end
+end # StandardTagTest
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/statements_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/statements_test.rb
new file mode 100644
index 0000000..eeff166
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/statements_test.rb
@@ -0,0 +1,111 @@
+require 'test_helper'
+
+class StatementsTest < Minitest::Test
+ include Liquid
+
+ def test_true_eql_true
+ text = ' {% if true == true %} true {% else %} false {% endif %} '
+ assert_template_result ' true ', text
+ end
+
+ def test_true_not_eql_true
+ text = ' {% if true != true %} true {% else %} false {% endif %} '
+ assert_template_result ' false ', text
+ end
+
+ def test_true_lq_true
+ text = ' {% if 0 > 0 %} true {% else %} false {% endif %} '
+ assert_template_result ' false ', text
+ end
+
+ def test_one_lq_zero
+ text = ' {% if 1 > 0 %} true {% else %} false {% endif %} '
+ assert_template_result ' true ', text
+ end
+
+ def test_zero_lq_one
+ text = ' {% if 0 < 1 %} true {% else %} false {% endif %} '
+ assert_template_result ' true ', text
+ end
+
+ def test_zero_lq_or_equal_one
+ text = ' {% if 0 <= 0 %} true {% else %} false {% endif %} '
+ assert_template_result ' true ', text
+ end
+
+ def test_zero_lq_or_equal_one_involving_nil
+ text = ' {% if null <= 0 %} true {% else %} false {% endif %} '
+ assert_template_result ' false ', text
+
+ text = ' {% if 0 <= null %} true {% else %} false {% endif %} '
+ assert_template_result ' false ', text
+ end
+
+ def test_zero_lqq_or_equal_one
+ text = ' {% if 0 >= 0 %} true {% else %} false {% endif %} '
+ assert_template_result ' true ', text
+ end
+
+ def test_strings
+ text = " {% if 'test' == 'test' %} true {% else %} false {% endif %} "
+ assert_template_result ' true ', text
+ end
+
+ def test_strings_not_equal
+ text = " {% if 'test' != 'test' %} true {% else %} false {% endif %} "
+ assert_template_result ' false ', text
+ end
+
+ def test_var_strings_equal
+ text = ' {% if var == "hello there!" %} true {% else %} false {% endif %} '
+ assert_template_result ' true ', text, 'var' => 'hello there!'
+ end
+
+ def test_var_strings_are_not_equal
+ text = ' {% if "hello there!" == var %} true {% else %} false {% endif %} '
+ assert_template_result ' true ', text, 'var' => 'hello there!'
+ end
+
+ def test_var_and_long_string_are_equal
+ text = " {% if var == 'hello there!' %} true {% else %} false {% endif %} "
+ assert_template_result ' true ', text, 'var' => 'hello there!'
+ end
+
+ def test_var_and_long_string_are_equal_backwards
+ text = " {% if 'hello there!' == var %} true {% else %} false {% endif %} "
+ assert_template_result ' true ', text, 'var' => 'hello there!'
+ end
+
+ # def test_is_nil
+ # text = %| {% if var != nil %} true {% else %} false {% end %} |
+ # @template.assigns = { 'var' => 'hello there!'}
+ # expected = %| true |
+ # assert_equal expected, @template.parse(text)
+ # end
+
+ def test_is_collection_empty
+ text = ' {% if array == empty %} true {% else %} false {% endif %} '
+ assert_template_result ' true ', text, 'array' => []
+ end
+
+ def test_is_not_collection_empty
+ text = ' {% if array == empty %} true {% else %} false {% endif %} '
+ assert_template_result ' false ', text, 'array' => [1, 2, 3]
+ end
+
+ def test_nil
+ text = ' {% if var == nil %} true {% else %} false {% endif %} '
+ assert_template_result ' true ', text, 'var' => nil
+
+ text = ' {% if var == null %} true {% else %} false {% endif %} '
+ assert_template_result ' true ', text, 'var' => nil
+ end
+
+ def test_not_nil
+ text = ' {% if var != nil %} true {% else %} false {% endif %} '
+ assert_template_result ' true ', text, 'var' => 1
+
+ text = ' {% if var != null %} true {% else %} false {% endif %} '
+ assert_template_result ' true ', text, 'var' => 1
+ end
+end # StatementsTest
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/table_row_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/table_row_test.rb
new file mode 100644
index 0000000..d7bc14c
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/table_row_test.rb
@@ -0,0 +1,64 @@
+require 'test_helper'
+
+class TableRowTest < Minitest::Test
+ include Liquid
+
+ class ArrayDrop < Liquid::Drop
+ include Enumerable
+
+ def initialize(array)
+ @array = array
+ end
+
+ def each(&block)
+ @array.each(&block)
+ end
+ end
+
+ def test_table_row
+ assert_template_result("<tr class=\"row1\">\n<td class=\"col1\"> 1 </td><td class=\"col2\"> 2 </td><td class=\"col3\"> 3 </td></tr>\n<tr class=\"row2\"><td class=\"col1\"> 4 </td><td class=\"col2\"> 5 </td><td class=\"col3\"> 6 </td></tr>\n",
+ '{% tablerow n in numbers cols:3%} {{n}} {% endtablerow %}',
+ 'numbers' => [1, 2, 3, 4, 5, 6])
+
+ assert_template_result("<tr class=\"row1\">\n</tr>\n",
+ '{% tablerow n in numbers cols:3%} {{n}} {% endtablerow %}',
+ 'numbers' => [])
+ end
+
+ def test_table_row_with_different_cols
+ assert_template_result("<tr class=\"row1\">\n<td class=\"col1\"> 1 </td><td class=\"col2\"> 2 </td><td class=\"col3\"> 3 </td><td class=\"col4\"> 4 </td><td class=\"col5\"> 5 </td></tr>\n<tr class=\"row2\"><td class=\"col1\"> 6 </td></tr>\n",
+ '{% tablerow n in numbers cols:5%} {{n}} {% endtablerow %}',
+ 'numbers' => [1, 2, 3, 4, 5, 6])
+ end
+
+ def test_table_col_counter
+ assert_template_result("<tr class=\"row1\">\n<td class=\"col1\">1</td><td class=\"col2\">2</td></tr>\n<tr class=\"row2\"><td class=\"col1\">1</td><td class=\"col2\">2</td></tr>\n<tr class=\"row3\"><td class=\"col1\">1</td><td class=\"col2\">2</td></tr>\n",
+ '{% tablerow n in numbers cols:2%}{{tablerowloop.col}}{% endtablerow %}',
+ 'numbers' => [1, 2, 3, 4, 5, 6])
+ end
+
+ def test_quoted_fragment
+ assert_template_result("<tr class=\"row1\">\n<td class=\"col1\"> 1 </td><td class=\"col2\"> 2 </td><td class=\"col3\"> 3 </td></tr>\n<tr class=\"row2\"><td class=\"col1\"> 4 </td><td class=\"col2\"> 5 </td><td class=\"col3\"> 6 </td></tr>\n",
+ "{% tablerow n in collections.frontpage cols:3%} {{n}} {% endtablerow %}",
+ 'collections' => { 'frontpage' => [1, 2, 3, 4, 5, 6] })
+ assert_template_result("<tr class=\"row1\">\n<td class=\"col1\"> 1 </td><td class=\"col2\"> 2 </td><td class=\"col3\"> 3 </td></tr>\n<tr class=\"row2\"><td class=\"col1\"> 4 </td><td class=\"col2\"> 5 </td><td class=\"col3\"> 6 </td></tr>\n",
+ "{% tablerow n in collections['frontpage'] cols:3%} {{n}} {% endtablerow %}",
+ 'collections' => { 'frontpage' => [1, 2, 3, 4, 5, 6] })
+ end
+
+ def test_enumerable_drop
+ assert_template_result("<tr class=\"row1\">\n<td class=\"col1\"> 1 </td><td class=\"col2\"> 2 </td><td class=\"col3\"> 3 </td></tr>\n<tr class=\"row2\"><td class=\"col1\"> 4 </td><td class=\"col2\"> 5 </td><td class=\"col3\"> 6 </td></tr>\n",
+ '{% tablerow n in numbers cols:3%} {{n}} {% endtablerow %}',
+ 'numbers' => ArrayDrop.new([1, 2, 3, 4, 5, 6]))
+ end
+
+ def test_offset_and_limit
+ assert_template_result("<tr class=\"row1\">\n<td class=\"col1\"> 1 </td><td class=\"col2\"> 2 </td><td class=\"col3\"> 3 </td></tr>\n<tr class=\"row2\"><td class=\"col1\"> 4 </td><td class=\"col2\"> 5 </td><td class=\"col3\"> 6 </td></tr>\n",
+ '{% tablerow n in numbers cols:3 offset:1 limit:6%} {{n}} {% endtablerow %}',
+ 'numbers' => [0, 1, 2, 3, 4, 5, 6, 7])
+ end
+
+ def test_blank_string_not_iterable
+ assert_template_result("<tr class=\"row1\">\n</tr>\n", "{% tablerow char in characters cols:3 %}I WILL NOT BE OUTPUT{% endtablerow %}", 'characters' => '')
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/unless_else_tag_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/unless_else_tag_test.rb
new file mode 100644
index 0000000..c414a71
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/tags/unless_else_tag_test.rb
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+class UnlessElseTagTest < Minitest::Test
+ include Liquid
+
+ def test_unless
+ assert_template_result(' ', ' {% unless true %} this text should not go into the output {% endunless %} ')
+ assert_template_result(' this text should go into the output ',
+ ' {% unless false %} this text should go into the output {% endunless %} ')
+ assert_template_result(' you rock ?', '{% unless true %} you suck {% endunless %} {% unless false %} you rock {% endunless %}?')
+ end
+
+ def test_unless_else
+ assert_template_result(' YES ', '{% unless true %} NO {% else %} YES {% endunless %}')
+ assert_template_result(' YES ', '{% unless false %} YES {% else %} NO {% endunless %}')
+ assert_template_result(' YES ', '{% unless "foo" %} NO {% else %} YES {% endunless %}')
+ end
+
+ def test_unless_in_loop
+ assert_template_result '23', '{% for i in choices %}{% unless i %}{{ forloop.index }}{% endunless %}{% endfor %}', 'choices' => [1, nil, false]
+ end
+
+ def test_unless_else_in_loop
+ assert_template_result ' TRUE 2 3 ', '{% for i in choices %}{% unless i %} {{ forloop.index }} {% else %} TRUE {% endunless %}{% endfor %}', 'choices' => [1, nil, false]
+ end
+end # UnlessElseTest
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/template_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/template_test.rb
new file mode 100644
index 0000000..d10e1c5
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/template_test.rb
@@ -0,0 +1,332 @@
+require 'test_helper'
+require 'timeout'
+
+class TemplateContextDrop < Liquid::Drop
+ def liquid_method_missing(method)
+ method
+ end
+
+ def foo
+ 'fizzbuzz'
+ end
+
+ def baz
+ @context.registers['lulz']
+ end
+end
+
+class SomethingWithLength < Liquid::Drop
+ def length
+ nil
+ end
+end
+
+class ErroneousDrop < Liquid::Drop
+ def bad_method
+ raise 'ruby error in drop'
+ end
+end
+
+class DropWithUndefinedMethod < Liquid::Drop
+ def foo
+ 'foo'
+ end
+end
+
+class TemplateTest < Minitest::Test
+ include Liquid
+
+ def test_instance_assigns_persist_on_same_template_object_between_parses
+ t = Template.new
+ assert_equal 'from instance assigns', t.parse("{% assign foo = 'from instance assigns' %}{{ foo }}").render!
+ assert_equal 'from instance assigns', t.parse("{{ foo }}").render!
+ end
+
+ def test_warnings_is_not_exponential_time
+ str = "false"
+ 100.times do
+ str = "{% if true %}true{% else %}#{str}{% endif %}"
+ end
+
+ t = Template.parse(str)
+ assert_equal [], Timeout.timeout(1) { t.warnings }
+ end
+
+ def test_instance_assigns_persist_on_same_template_parsing_between_renders
+ t = Template.new.parse("{{ foo }}{% assign foo = 'foo' %}{{ foo }}")
+ assert_equal 'foo', t.render!
+ assert_equal 'foofoo', t.render!
+ end
+
+ def test_custom_assigns_do_not_persist_on_same_template
+ t = Template.new
+ assert_equal 'from custom assigns', t.parse("{{ foo }}").render!('foo' => 'from custom assigns')
+ assert_equal '', t.parse("{{ foo }}").render!
+ end
+
+ def test_custom_assigns_squash_instance_assigns
+ t = Template.new
+ assert_equal 'from instance assigns', t.parse("{% assign foo = 'from instance assigns' %}{{ foo }}").render!
+ assert_equal 'from custom assigns', t.parse("{{ foo }}").render!('foo' => 'from custom assigns')
+ end
+
+ def test_persistent_assigns_squash_instance_assigns
+ t = Template.new
+ assert_equal 'from instance assigns', t.parse("{% assign foo = 'from instance assigns' %}{{ foo }}").render!
+ t.assigns['foo'] = 'from persistent assigns'
+ assert_equal 'from persistent assigns', t.parse("{{ foo }}").render!
+ end
+
+ def test_lambda_is_called_once_from_persistent_assigns_over_multiple_parses_and_renders
+ t = Template.new
+ t.assigns['number'] = -> { @global ||= 0; @global += 1 }
+ assert_equal '1', t.parse("{{number}}").render!
+ assert_equal '1', t.parse("{{number}}").render!
+ assert_equal '1', t.render!
+ @global = nil
+ end
+
+ def test_lambda_is_called_once_from_custom_assigns_over_multiple_parses_and_renders
+ t = Template.new
+ assigns = { 'number' => -> { @global ||= 0; @global += 1 } }
+ assert_equal '1', t.parse("{{number}}").render!(assigns)
+ assert_equal '1', t.parse("{{number}}").render!(assigns)
+ assert_equal '1', t.render!(assigns)
+ @global = nil
+ end
+
+ def test_resource_limits_works_with_custom_length_method
+ t = Template.parse("{% assign foo = bar %}")
+ t.resource_limits.render_length_limit = 42
+ assert_equal "", t.render!("bar" => SomethingWithLength.new)
+ end
+
+ def test_resource_limits_render_length
+ t = Template.parse("0123456789")
+ t.resource_limits.render_length_limit = 5
+ assert_equal "Liquid error: Memory limits exceeded", t.render
+ assert t.resource_limits.reached?
+
+ t.resource_limits.render_length_limit = 10
+ assert_equal "0123456789", t.render!
+ refute_nil t.resource_limits.render_length
+ end
+
+ def test_resource_limits_render_score
+ t = Template.parse("{% for a in (1..10) %} {% for a in (1..10) %} foo {% endfor %} {% endfor %}")
+ t.resource_limits.render_score_limit = 50
+ assert_equal "Liquid error: Memory limits exceeded", t.render
+ assert t.resource_limits.reached?
+
+ t = Template.parse("{% for a in (1..100) %} foo {% endfor %}")
+ t.resource_limits.render_score_limit = 50
+ assert_equal "Liquid error: Memory limits exceeded", t.render
+ assert t.resource_limits.reached?
+
+ t.resource_limits.render_score_limit = 200
+ assert_equal (" foo " * 100), t.render!
+ refute_nil t.resource_limits.render_score
+ end
+
+ def test_resource_limits_assign_score
+ t = Template.parse("{% assign foo = 42 %}{% assign bar = 23 %}")
+ t.resource_limits.assign_score_limit = 1
+ assert_equal "Liquid error: Memory limits exceeded", t.render
+ assert t.resource_limits.reached?
+
+ t.resource_limits.assign_score_limit = 2
+ assert_equal "", t.render!
+ refute_nil t.resource_limits.assign_score
+ end
+
+ def test_resource_limits_assign_score_nested
+ t = Template.parse("{% assign foo = 'aaaa' | reverse %}")
+
+ t.resource_limits.assign_score_limit = 3
+ assert_equal "Liquid error: Memory limits exceeded", t.render
+ assert t.resource_limits.reached?
+
+ t.resource_limits.assign_score_limit = 5
+ assert_equal "", t.render!
+ end
+
+ def test_resource_limits_aborts_rendering_after_first_error
+ t = Template.parse("{% for a in (1..100) %} foo1 {% endfor %} bar {% for a in (1..100) %} foo2 {% endfor %}")
+ t.resource_limits.render_score_limit = 50
+ assert_equal "Liquid error: Memory limits exceeded", t.render
+ assert t.resource_limits.reached?
+ end
+
+ def test_resource_limits_hash_in_template_gets_updated_even_if_no_limits_are_set
+ t = Template.parse("{% for a in (1..100) %} {% assign foo = 1 %} {% endfor %}")
+ t.render!
+ assert t.resource_limits.assign_score > 0
+ assert t.resource_limits.render_score > 0
+ assert t.resource_limits.render_length > 0
+ end
+
+ def test_render_length_persists_between_blocks
+ t = Template.parse("{% if true %}aaaa{% endif %}")
+ t.resource_limits.render_length_limit = 7
+ assert_equal "Liquid error: Memory limits exceeded", t.render
+ t.resource_limits.render_length_limit = 8
+ assert_equal "aaaa", t.render
+
+ t = Template.parse("{% if true %}aaaa{% endif %}{% if true %}bbb{% endif %}")
+ t.resource_limits.render_length_limit = 13
+ assert_equal "Liquid error: Memory limits exceeded", t.render
+ t.resource_limits.render_length_limit = 14
+ assert_equal "aaaabbb", t.render
+
+ t = Template.parse("{% if true %}a{% endif %}{% if true %}b{% endif %}{% if true %}a{% endif %}{% if true %}b{% endif %}{% if true %}a{% endif %}{% if true %}b{% endif %}")
+ t.resource_limits.render_length_limit = 5
+ assert_equal "Liquid error: Memory limits exceeded", t.render
+ t.resource_limits.render_length_limit = 11
+ assert_equal "Liquid error: Memory limits exceeded", t.render
+ t.resource_limits.render_length_limit = 12
+ assert_equal "ababab", t.render
+ end
+
+ def test_default_resource_limits_unaffected_by_render_with_context
+ context = Context.new
+ t = Template.parse("{% for a in (1..100) %} {% assign foo = 1 %} {% endfor %}")
+ t.render!(context)
+ assert context.resource_limits.assign_score > 0
+ assert context.resource_limits.render_score > 0
+ assert context.resource_limits.render_length > 0
+ end
+
+ def test_can_use_drop_as_context
+ t = Template.new
+ t.registers['lulz'] = 'haha'
+ drop = TemplateContextDrop.new
+ assert_equal 'fizzbuzz', t.parse('{{foo}}').render!(drop)
+ assert_equal 'bar', t.parse('{{bar}}').render!(drop)
+ assert_equal 'haha', t.parse("{{baz}}").render!(drop)
+ end
+
+ def test_render_bang_force_rethrow_errors_on_passed_context
+ context = Context.new({ 'drop' => ErroneousDrop.new })
+ t = Template.new.parse('{{ drop.bad_method }}')
+
+ e = assert_raises RuntimeError do
+ t.render!(context)
+ end
+ assert_equal 'ruby error in drop', e.message
+ end
+
+ def test_exception_renderer_that_returns_string
+ exception = nil
+ handler = ->(e) { exception = e; '<!-- error -->' }
+
+ output = Template.parse("{{ 1 | divided_by: 0 }}").render({}, exception_renderer: handler)
+
+ assert exception.is_a?(Liquid::ZeroDivisionError)
+ assert_equal '<!-- error -->', output
+ end
+
+ def test_exception_renderer_that_raises
+ exception = nil
+ assert_raises(Liquid::ZeroDivisionError) do
+ Template.parse("{{ 1 | divided_by: 0 }}").render({}, exception_renderer: ->(e) { exception = e; raise })
+ end
+ assert exception.is_a?(Liquid::ZeroDivisionError)
+ end
+
+ def test_global_filter_option_on_render
+ global_filter_proc = ->(output) { "#{output} filtered" }
+ rendered_template = Template.parse("{{name}}").render({ "name" => "bob" }, global_filter: global_filter_proc)
+
+ assert_equal 'bob filtered', rendered_template
+ end
+
+ def test_global_filter_option_when_native_filters_exist
+ global_filter_proc = ->(output) { "#{output} filtered" }
+ rendered_template = Template.parse("{{name | upcase}}").render({ "name" => "bob" }, global_filter: global_filter_proc)
+
+ assert_equal 'BOB filtered', rendered_template
+ end
+
+ def test_undefined_variables
+ t = Template.parse("{{x}} {{y}} {{z.a}} {{z.b}} {{z.c.d}}")
+ result = t.render({ 'x' => 33, 'z' => { 'a' => 32, 'c' => { 'e' => 31 } } }, { strict_variables: true })
+
+ assert_equal '33 32 ', result
+ assert_equal 3, t.errors.count
+ assert_instance_of Liquid::UndefinedVariable, t.errors[0]
+ assert_equal 'Liquid error: undefined variable y', t.errors[0].message
+ assert_instance_of Liquid::UndefinedVariable, t.errors[1]
+ assert_equal 'Liquid error: undefined variable b', t.errors[1].message
+ assert_instance_of Liquid::UndefinedVariable, t.errors[2]
+ assert_equal 'Liquid error: undefined variable d', t.errors[2].message
+ end
+
+ def test_nil_value_does_not_raise
+ Liquid::Template.error_mode = :strict
+ t = Template.parse("some{{x}}thing")
+ result = t.render!({ 'x' => nil }, strict_variables: true)
+
+ assert_equal 0, t.errors.count
+ assert_equal 'something', result
+ end
+
+ def test_undefined_variables_raise
+ t = Template.parse("{{x}} {{y}} {{z.a}} {{z.b}} {{z.c.d}}")
+
+ assert_raises UndefinedVariable do
+ t.render!({ 'x' => 33, 'z' => { 'a' => 32, 'c' => { 'e' => 31 } } }, { strict_variables: true })
+ end
+ end
+
+ def test_undefined_drop_methods
+ d = DropWithUndefinedMethod.new
+ t = Template.new.parse('{{ foo }} {{ woot }}')
+ result = t.render(d, { strict_variables: true })
+
+ assert_equal 'foo ', result
+ assert_equal 1, t.errors.count
+ assert_instance_of Liquid::UndefinedDropMethod, t.errors[0]
+ end
+
+ def test_undefined_drop_methods_raise
+ d = DropWithUndefinedMethod.new
+ t = Template.new.parse('{{ foo }} {{ woot }}')
+
+ assert_raises UndefinedDropMethod do
+ t.render!(d, { strict_variables: true })
+ end
+ end
+
+ def test_undefined_filters
+ t = Template.parse("{{a}} {{x | upcase | somefilter1 | somefilter2 | somefilter3}}")
+ filters = Module.new do
+ def somefilter3(v)
+ "-#{v}-"
+ end
+ end
+ result = t.render({ 'a' => 123, 'x' => 'foo' }, { filters: [filters], strict_filters: true })
+
+ assert_equal '123 ', result
+ assert_equal 1, t.errors.count
+ assert_instance_of Liquid::UndefinedFilter, t.errors[0]
+ assert_equal 'Liquid error: undefined filter somefilter1', t.errors[0].message
+ end
+
+ def test_undefined_filters_raise
+ t = Template.parse("{{x | somefilter1 | upcase | somefilter2}}")
+
+ assert_raises UndefinedFilter do
+ t.render!({ 'x' => 'foo' }, { strict_filters: true })
+ end
+ end
+
+ def test_using_range_literal_works_as_expected
+ t = Template.parse("{% assign foo = (x..y) %}{{ foo }}")
+ result = t.render({ 'x' => 1, 'y' => 5 })
+ assert_equal '1..5', result
+
+ t = Template.parse("{% assign nums = (x..y) %}{% for num in nums %}{{ num }}{% endfor %}")
+ result = t.render({ 'x' => 1, 'y' => 5 })
+ assert_equal '12345', result
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/trim_mode_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/trim_mode_test.rb
new file mode 100644
index 0000000..52248cf
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/trim_mode_test.rb
@@ -0,0 +1,529 @@
+require 'test_helper'
+
+class TrimModeTest < Minitest::Test
+ include Liquid
+
+ # Make sure the trim isn't applied to standard output
+ def test_standard_output
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {{ 'John' }}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>
+ John
+ </p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+ end
+
+ def test_variable_output_with_multiple_blank_lines
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+
+
+ {{- 'John' -}}
+
+
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>John</p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+ end
+
+ def test_tag_output_with_multiple_blank_lines
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+
+
+ {%- if true -%}
+ yes
+ {%- endif -%}
+
+
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>yes</p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+ end
+
+ # Make sure the trim isn't applied to standard tags
+ def test_standard_tags
+ whitespace = ' '
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {% if true %}
+ yes
+ {% endif %}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>
+#{whitespace}
+ yes
+#{whitespace}
+ </p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {% if false %}
+ no
+ {% endif %}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>
+#{whitespace}
+ </p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+ end
+
+ # Make sure the trim isn't too agressive
+ def test_no_trim_output
+ text = '<p>{{- \'John\' -}}</p>'
+ expected = '<p>John</p>'
+ assert_template_result(expected, text)
+ end
+
+ # Make sure the trim isn't too agressive
+ def test_no_trim_tags
+ text = '<p>{%- if true -%}yes{%- endif -%}</p>'
+ expected = '<p>yes</p>'
+ assert_template_result(expected, text)
+
+ text = '<p>{%- if false -%}no{%- endif -%}</p>'
+ expected = '<p></p>'
+ assert_template_result(expected, text)
+ end
+
+ def test_single_line_outer_tag
+ text = '<p> {%- if true %} yes {% endif -%} </p>'
+ expected = '<p> yes </p>'
+ assert_template_result(expected, text)
+
+ text = '<p> {%- if false %} no {% endif -%} </p>'
+ expected = '<p></p>'
+ assert_template_result(expected, text)
+ end
+
+ def test_single_line_inner_tag
+ text = '<p> {% if true -%} yes {%- endif %} </p>'
+ expected = '<p> yes </p>'
+ assert_template_result(expected, text)
+
+ text = '<p> {% if false -%} no {%- endif %} </p>'
+ expected = '<p> </p>'
+ assert_template_result(expected, text)
+ end
+
+ def test_single_line_post_tag
+ text = '<p> {% if true -%} yes {% endif -%} </p>'
+ expected = '<p> yes </p>'
+ assert_template_result(expected, text)
+
+ text = '<p> {% if false -%} no {% endif -%} </p>'
+ expected = '<p> </p>'
+ assert_template_result(expected, text)
+ end
+
+ def test_single_line_pre_tag
+ text = '<p> {%- if true %} yes {%- endif %} </p>'
+ expected = '<p> yes </p>'
+ assert_template_result(expected, text)
+
+ text = '<p> {%- if false %} no {%- endif %} </p>'
+ expected = '<p> </p>'
+ assert_template_result(expected, text)
+ end
+
+ def test_pre_trim_output
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {{- 'John' }}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>John
+ </p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+ end
+
+ def test_pre_trim_tags
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {%- if true %}
+ yes
+ {%- endif %}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>
+ yes
+ </p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {%- if false %}
+ no
+ {%- endif %}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>
+ </p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+ end
+
+ def test_post_trim_output
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {{ 'John' -}}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>
+ John</p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+ end
+
+ def test_post_trim_tags
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {% if true -%}
+ yes
+ {% endif -%}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>
+ yes
+ </p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {% if false -%}
+ no
+ {% endif -%}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>
+ </p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+ end
+
+ def test_pre_and_post_trim_tags
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {%- if true %}
+ yes
+ {% endif -%}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>
+ yes
+ </p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {%- if false %}
+ no
+ {% endif -%}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p></p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+ end
+
+ def test_post_and_pre_trim_tags
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {% if true -%}
+ yes
+ {%- endif %}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>
+ yes
+ </p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+
+ whitespace = ' '
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {% if false -%}
+ no
+ {%- endif %}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>
+#{whitespace}
+ </p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+ end
+
+ def test_trim_output
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {{- 'John' -}}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>John</p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+ end
+
+ def test_trim_tags
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {%- if true -%}
+ yes
+ {%- endif -%}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>yes</p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {%- if false -%}
+ no
+ {%- endif -%}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p></p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+ end
+
+ def test_whitespace_trim_output
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {{- 'John' -}},
+ {{- '30' -}}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>John,30</p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+ end
+
+ def test_whitespace_trim_tags
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {%- if true -%}
+ yes
+ {%- endif -%}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>yes</p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {%- if false -%}
+ no
+ {%- endif -%}
+ </p>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p></p>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+ end
+
+ def test_complex_trim_output
+ text = <<-END_TEMPLATE
+ <div>
+ <p>
+ {{- 'John' -}}
+ {{- '30' -}}
+ </p>
+ <b>
+ {{ 'John' -}}
+ {{- '30' }}
+ </b>
+ <i>
+ {{- 'John' }}
+ {{ '30' -}}
+ </i>
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+ <p>John30</p>
+ <b>
+ John30
+ </b>
+ <i>John
+ 30</i>
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+ end
+
+ def test_complex_trim
+ text = <<-END_TEMPLATE
+ <div>
+ {%- if true -%}
+ {%- if true -%}
+ <p>
+ {{- 'John' -}}
+ </p>
+ {%- endif -%}
+ {%- endif -%}
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div><p>John</p></div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+ end
+
+ def test_right_trim_followed_by_tag
+ assert_template_result('ab c', '{{ "a" -}}{{ "b" }} c')
+ end
+
+ def test_raw_output
+ whitespace = ' '
+ text = <<-END_TEMPLATE
+ <div>
+ {% raw %}
+ {%- if true -%}
+ <p>
+ {{- 'John' -}}
+ </p>
+ {%- endif -%}
+ {% endraw %}
+ </div>
+ END_TEMPLATE
+ expected = <<-END_EXPECTED
+ <div>
+#{whitespace}
+ {%- if true -%}
+ <p>
+ {{- 'John' -}}
+ </p>
+ {%- endif -%}
+#{whitespace}
+ </div>
+ END_EXPECTED
+ assert_template_result(expected, text)
+ end
+end # TrimModeTest
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/variable_test.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/variable_test.rb
new file mode 100644
index 0000000..abd6e70
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/test/integration/variable_test.rb
@@ -0,0 +1,96 @@
+require 'test_helper'
+
+class VariableTest < Minitest::Test
+ include Liquid
+
+ def test_simple_variable
+ template = Template.parse(%({{test}}))
+ assert_equal 'worked', template.render!('test' => 'worked')
+ assert_equal 'worked wonderfully', template.render!('test' => 'worked wonderfully')
+ end
+
+ def test_variable_render_calls_to_liquid
+ assert_template_result 'foobar', '{{ foo }}', 'foo' => ThingWithToLiquid.new
+ end
+
+ def test_simple_with_whitespaces
+ template = Template.parse(%( {{ test }} ))
+ assert_equal ' worked ', template.render!('test' => 'worked')
+ assert_equal ' worked wonderfully ', template.render!('test' => 'worked wonderfully')
+ end
+
+ def test_ignore_unknown
+ template = Template.parse(%({{ test }}))
+ assert_equal '', template.render!
+ end
+
+ def test_using_blank_as_variable_name
+ template = Template.parse("{% assign foo = blank %}{{ foo }}")
+ assert_equal '', template.render!
+ end
+
+ def test_using_empty_as_variable_name
+ template = Template.parse("{% assign foo = empty %}{{ foo }}")
+ assert_equal '', template.render!
+ end
+
+ def test_hash_scoping
+ template = Template.parse(%({{ test.test }}))
+ assert_equal 'worked', template.render!('test' => { 'test' => 'worked' })
+ end
+
+ def test_false_renders_as_false
+ assert_equal 'false', Template.parse("{{ foo }}").render!('foo' => false)
+ assert_equal 'false', Template.parse("{{ false }}").render!
+ end
+
+ def test_nil_renders_as_empty_string
+ assert_equal '', Template.parse("{{ nil }}").render!
+ assert_equal 'cat', Template.parse("{{ nil | append: 'cat' }}").render!
+ end
+
+ def test_preset_assigns
+ template = Template.parse(%({{ test }}))
+ template.assigns['test'] = 'worked'
+ assert_equal 'worked', template.render!
+ end
+
+ def test_reuse_parsed_template
+ template = Template.parse(%({{ greeting }} {{ name }}))
+ template.assigns['greeting'] = 'Goodbye'
+ assert_equal 'Hello Tobi', template.render!('greeting' => 'Hello', 'name' => 'Tobi')
+ assert_equal 'Hello ', template.render!('greeting' => 'Hello', 'unknown' => 'Tobi')
+ assert_equal 'Hello Brian', template.render!('greeting' => 'Hello', 'name' => 'Brian')
+ assert_equal 'Goodbye Brian', template.render!('name' => 'Brian')
+ assert_equal({ 'greeting' => 'Goodbye' }, template.assigns)
+ end
+
+ def test_assigns_not_polluted_from_template
+ template = Template.parse(%({{ test }}{% assign test = 'bar' %}{{ test }}))
+ template.assigns['test'] = 'baz'
+ assert_equal 'bazbar', template.render!
+ assert_equal 'bazbar', template.render!
+ assert_equal 'foobar', template.render!('test' => 'foo')
+ assert_equal 'bazbar', template.render!
+ end
+
+ def test_hash_with_default_proc
+ template = Template.parse(%(Hello {{ test }}))
+ assigns = Hash.new { |h, k| raise "Unknown variable '#{k}'" }
+ assigns['test'] = 'Tobi'
+ assert_equal 'Hello Tobi', template.render!(assigns)
+ assigns.delete('test')
+ e = assert_raises(RuntimeError) do
+ template.render!(assigns)
+ end
+ assert_equal "Unknown variable 'test'", e.message
+ end
+
+ def test_multiline_variable
+ assert_equal 'worked', Template.parse("{{\ntest\n}}").render!('test' => 'worked')
+ end
+
+ def test_render_symbol
+ assert_template_result 'bar', '{{ foo }}', 'foo' => :bar
+ end
+end