Skip to content

Commit

Permalink
Added backwards compatibility for 1.8.7 String.each returning itself …
Browse files Browse the repository at this point in the history
…(and 1.9.3 not supporting .each).

Moved for tag tests to their own test model from StandardTagTest.
  • Loading branch information
kristianpd committed Jan 20, 2012
1 parent 1a1b470 commit 01dea94
Show file tree
Hide file tree
Showing 3 changed files with 205 additions and 167 deletions.
7 changes: 6 additions & 1 deletion lib/liquid/tags/for.rb
Expand Up @@ -75,7 +75,8 @@ def render(context)
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
Expand Down Expand Up @@ -123,6 +124,10 @@ def slice_collection_using_each(collection, from, to)
segments = []
index = 0
yielded = 0

# 1.8.7 compatibility
return [collection] if collection.is_a?(String)

collection.each do |item|

if to && to <= index
Expand Down
199 changes: 199 additions & 0 deletions 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 = <<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%}')
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

0 comments on commit 01dea94

Please sign in to comment.