diff --git a/lib/liquid/tags/for.rb b/lib/liquid/tags/for.rb index ec475d2..740e90f 100644 --- a/lib/liquid/tags/for.rb +++ b/lib/liquid/tags/for.rb @@ -75,7 +75,8 @@ module Liquid collection = context[@collection_name] collection = collection.to_a if collection.is_a?(Range) - return render_else(context) unless collection.respond_to?(:each) + # 1.8.7 compatibility + return render_else(context) unless collection.respond_to?(:each) or collection.is_a?(String) from = if @attributes['offset'] == 'continue' context.registers[:for][@name].to_i @@ -123,6 +124,10 @@ module Liquid segments = [] index = 0 yielded = 0 + + # 1.8.7 compatibility + return [collection] if collection.is_a?(String) + collection.each do |item| if to && to <= index diff --git a/test/liquid/tags/for_tag_test.rb b/test/liquid/tags/for_tag_test.rb new file mode 100644 index 0000000..0324051 --- /dev/null +++ b/test/liquid/tags/for_tag_test.rb @@ -0,0 +1,199 @@ +require 'test_helper' + +class ForTagTest < Test::Unit::TestCase + 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 = < [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%}') + 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 = %q({%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 = %q(123 + next + 456 + next + ) + 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") + + fields = %w(name length index index0 rindex rindex0 first last) + 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 +end diff --git a/test/liquid/tags/standard_tag_test.rb b/test/liquid/tags/standard_tag_test.rb index 46c1a7f..4d8bdd3 100644 --- a/test/liquid/tags/standard_tag_test.rb +++ b/test/liquid/tags/standard_tag_test.rb @@ -47,166 +47,6 @@ class StandardTagTest < Test::Unit::TestCase {%endcomment%}bar') end - 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 = < [1,2,3]) - end - - def test_for_with_range - assert_template_result(' 1 2 3 ','{%for item in (1..3) %} {{item}} {%endfor%}') - 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 = %q({%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 = %q(123 - next - 456 - next - ) - assert_template_result(expected,markup,assigns) - end - def test_assign assigns = {'var' => 'content' } assert_template_result('var2: var2:content', 'var2:{{var2}} {%assign var2 = var%} var2:{{var2}}', assigns) @@ -445,12 +285,6 @@ HERE assert_template_result('', '{% if null == true %}?{% endif %}', {}) 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_ifchanged assigns = {'array' => [ 1, 1, 2, 2, 3, 3] } assert_template_result('123','{%for item in array%}{%ifchanged%}{{item}}{% endifchanged %}{%endfor%}',assigns)