liquid 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +38 -0
- data/MIT-LICENSE +20 -0
- data/Manifest.txt +60 -0
- data/README +38 -0
- data/Rakefile +24 -0
- data/example/server/example_servlet.rb +37 -0
- data/example/server/liquid_servlet.rb +28 -0
- data/example/server/server.rb +12 -0
- data/example/server/templates/index.liquid +6 -0
- data/example/server/templates/products.liquid +45 -0
- data/init.rb +6 -0
- data/lib/extras/liquid_view.rb +27 -0
- data/lib/liquid.rb +66 -0
- data/lib/liquid/block.rb +101 -0
- data/lib/liquid/condition.rb +91 -0
- data/lib/liquid/context.rb +216 -0
- data/lib/liquid/document.rb +17 -0
- data/lib/liquid/drop.rb +48 -0
- data/lib/liquid/errors.rb +7 -0
- data/lib/liquid/extensions.rb +56 -0
- data/lib/liquid/file_system.rb +62 -0
- data/lib/liquid/htmltags.rb +64 -0
- data/lib/liquid/standardfilters.rb +125 -0
- data/lib/liquid/strainer.rb +43 -0
- data/lib/liquid/tag.rb +25 -0
- data/lib/liquid/tags/assign.rb +22 -0
- data/lib/liquid/tags/capture.rb +22 -0
- data/lib/liquid/tags/case.rb +68 -0
- data/lib/liquid/tags/comment.rb +9 -0
- data/lib/liquid/tags/cycle.rb +46 -0
- data/lib/liquid/tags/for.rb +81 -0
- data/lib/liquid/tags/if.rb +51 -0
- data/lib/liquid/tags/ifchanged.rb +20 -0
- data/lib/liquid/tags/include.rb +56 -0
- data/lib/liquid/tags/unless.rb +29 -0
- data/lib/liquid/template.rb +150 -0
- data/lib/liquid/variable.rb +39 -0
- data/test/block_test.rb +50 -0
- data/test/context_test.rb +340 -0
- data/test/drop_test.rb +139 -0
- data/test/error_handling_test.rb +65 -0
- data/test/extra/breakpoint.rb +547 -0
- data/test/extra/caller.rb +80 -0
- data/test/file_system_test.rb +30 -0
- data/test/filter_test.rb +98 -0
- data/test/helper.rb +20 -0
- data/test/html_tag_test.rb +24 -0
- data/test/if_else_test.rb +95 -0
- data/test/include_tag_test.rb +91 -0
- data/test/output_test.rb +121 -0
- data/test/parsing_quirks_test.rb +14 -0
- data/test/regexp_test.rb +39 -0
- data/test/security_test.rb +41 -0
- data/test/standard_filter_test.rb +101 -0
- data/test/standard_tag_test.rb +336 -0
- data/test/statements_test.rb +137 -0
- data/test/strainer_test.rb +16 -0
- data/test/template_test.rb +26 -0
- data/test/unless_else_test.rb +19 -0
- data/test/variable_test.rb +135 -0
- metadata +114 -0
data/test/output_test.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.dirname(__FILE__) + '/helper'
|
3
|
+
|
4
|
+
module FunnyFilter
|
5
|
+
|
6
|
+
def make_funny(input)
|
7
|
+
'LOL'
|
8
|
+
end
|
9
|
+
|
10
|
+
def cite_funny(input)
|
11
|
+
"LOL: #{input}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_smiley(input, smiley = ":-)")
|
15
|
+
"#{input} #{smiley}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_tag(input, tag = "p", id = "foo")
|
19
|
+
%|<#{tag} id="#{id}">#{input}</#{tag}>|
|
20
|
+
end
|
21
|
+
|
22
|
+
def paragraph(input)
|
23
|
+
"<p>#{input}</p>"
|
24
|
+
end
|
25
|
+
|
26
|
+
def link_to(name, url)
|
27
|
+
%|<a href="#{url}">#{name}</a>|
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
class OutputTest < Test::Unit::TestCase
|
33
|
+
include Liquid
|
34
|
+
|
35
|
+
def setup
|
36
|
+
@assigns = {
|
37
|
+
'best_cars' => 'bmw',
|
38
|
+
'car' => {'bmw' => 'good', 'gm' => 'bad'}
|
39
|
+
}
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_variable
|
44
|
+
text = %| {{best_cars}} |
|
45
|
+
|
46
|
+
expected = %| bmw |
|
47
|
+
assert_equal expected, Template.parse(text).render(@assigns)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_variable_traversing
|
51
|
+
text = %| {{car.bmw}} {{car.gm}} {{car.bmw}} |
|
52
|
+
|
53
|
+
expected = %| good bad good |
|
54
|
+
assert_equal expected, Template.parse(text).render(@assigns)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_variable_piping
|
58
|
+
text = %( {{ car.gm | make_funny }} )
|
59
|
+
expected = %| LOL |
|
60
|
+
|
61
|
+
assert_equal expected, Template.parse(text).render(@assigns, :filters => [FunnyFilter])
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_variable_piping_with_input
|
65
|
+
text = %( {{ car.gm | cite_funny }} )
|
66
|
+
expected = %| LOL: bad |
|
67
|
+
|
68
|
+
assert_equal expected, Template.parse(text).render(@assigns, :filters => [FunnyFilter])
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_variable_piping_with_args
|
72
|
+
text = %! {{ car.gm | add_smiley : ':-(' }} !
|
73
|
+
expected = %| bad :-( |
|
74
|
+
|
75
|
+
assert_equal expected, Template.parse(text).render(@assigns, :filters => [FunnyFilter])
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_variable_piping_with_no_args
|
79
|
+
text = %! {{ car.gm | add_smiley }} !
|
80
|
+
expected = %| bad :-) |
|
81
|
+
|
82
|
+
assert_equal expected, Template.parse(text).render(@assigns, :filters => [FunnyFilter])
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_multiple_variable_piping_with_args
|
86
|
+
text = %! {{ car.gm | add_smiley : ':-(' | add_smiley : ':-('}} !
|
87
|
+
expected = %| bad :-( :-( |
|
88
|
+
|
89
|
+
assert_equal expected, Template.parse(text).render(@assigns, :filters => [FunnyFilter])
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_variable_piping_with_args
|
93
|
+
text = %! {{ car.gm | add_tag : 'span', 'bar'}} !
|
94
|
+
expected = %| <span id="bar">bad</span> |
|
95
|
+
|
96
|
+
assert_equal expected, Template.parse(text).render(@assigns, :filters => [FunnyFilter])
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_variable_piping_with_variable_args
|
100
|
+
text = %! {{ car.gm | add_tag : 'span', car.bmw}} !
|
101
|
+
expected = %| <span id="good">bad</span> |
|
102
|
+
|
103
|
+
assert_equal expected, Template.parse(text).render(@assigns, :filters => [FunnyFilter])
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_multiple_pipings
|
107
|
+
text = %( {{ best_cars | cite_funny | paragraph }} )
|
108
|
+
expected = %| <p>LOL: bmw</p> |
|
109
|
+
|
110
|
+
assert_equal expected, Template.parse(text).render(@assigns, :filters => [FunnyFilter])
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_link_to
|
114
|
+
text = %( {{ 'Typo' | link_to: 'http://typo.leetsoft.com' }} )
|
115
|
+
expected = %| <a href="http://typo.leetsoft.com">Typo</a> |
|
116
|
+
|
117
|
+
assert_equal expected, Template.parse(text).render(@assigns, :filters => [FunnyFilter])
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.dirname(__FILE__) + '/helper'
|
3
|
+
|
4
|
+
class ParsingQuirksTest < Test::Unit::TestCase
|
5
|
+
include Liquid
|
6
|
+
|
7
|
+
def test_error_with_css
|
8
|
+
text = %| div { font-weight: bold; } |
|
9
|
+
template = Template.parse(text)
|
10
|
+
|
11
|
+
assert_equal text, template.render
|
12
|
+
assert_equal [String], template.root.nodelist.collect {|i| i.class}
|
13
|
+
end
|
14
|
+
end
|
data/test/regexp_test.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class RegexpTest < Test::Unit::TestCase
|
4
|
+
include Liquid
|
5
|
+
|
6
|
+
def test_empty
|
7
|
+
assert_equal [], ''.scan(QuotedFragment)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_quote
|
11
|
+
assert_equal ['"arg 1"'], '"arg 1"'.scan(QuotedFragment)
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
def test_words
|
16
|
+
assert_equal ['arg1', 'arg2'], 'arg1 arg2'.scan(QuotedFragment)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_quoted_words
|
20
|
+
assert_equal ['arg1', 'arg2', '"arg 3"'], 'arg1 arg2 "arg 3"'.scan(QuotedFragment)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_quoted_words
|
24
|
+
assert_equal ['arg1', 'arg2', "'arg 3'"], 'arg1 arg2 \'arg 3\''.scan(QuotedFragment)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_quoted_words_in_the_middle
|
28
|
+
assert_equal ['arg1', 'arg2', '"arg 3"', 'arg4'], 'arg1 arg2 "arg 3" arg4 '.scan(QuotedFragment)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_variable_parser
|
32
|
+
assert_equal ['var'], 'var'.scan(VariableParser)
|
33
|
+
assert_equal ['var', 'method'], 'var.method'.scan(VariableParser)
|
34
|
+
assert_equal ['var', 'method'], 'var[method]'.scan(VariableParser)
|
35
|
+
assert_equal ['var', 'method', '0'], 'var[method][0]'.scan(VariableParser)
|
36
|
+
assert_equal ['var', 'method', '0', 'method'], 'var[method][0].method'.scan(VariableParser)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
module SecurityFilter
|
4
|
+
def add_one(input)
|
5
|
+
"#{input} + 1"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class SecurityTest < Test::Unit::TestCase
|
10
|
+
include Liquid
|
11
|
+
|
12
|
+
def test_no_instance_eval
|
13
|
+
text = %( {{ '1+1' | instance_eval }} )
|
14
|
+
expected = %| 1+1 |
|
15
|
+
|
16
|
+
assert_equal expected, Template.parse(text).render(@assigns)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_no_existing_instance_eval
|
20
|
+
text = %( {{ '1+1' | __instance_eval__ }} )
|
21
|
+
expected = %| 1+1 |
|
22
|
+
|
23
|
+
assert_equal expected, Template.parse(text).render(@assigns)
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def test_no_instance_eval_after_mixing_in_new_filter
|
28
|
+
text = %( {{ '1+1' | instance_eval }} )
|
29
|
+
expected = %| 1+1 |
|
30
|
+
|
31
|
+
assert_equal expected, Template.parse(text).render(@assigns)
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def test_no_instance_eval_later_in_chain
|
36
|
+
text = %( {{ '1+1' | add_one | instance_eval }} )
|
37
|
+
expected = %| 1+1 + 1 |
|
38
|
+
|
39
|
+
assert_equal expected, Template.parse(text).render(@assigns, :filters => SecurityFilter)
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.dirname(__FILE__) + '/helper'
|
3
|
+
|
4
|
+
|
5
|
+
class Filters
|
6
|
+
include Liquid::StandardFilters
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
class StandardFiltersTest < Test::Unit::TestCase
|
11
|
+
include Liquid
|
12
|
+
|
13
|
+
def setup
|
14
|
+
@filters = Filters.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_size
|
18
|
+
assert_equal 3, @filters.size([1,2,3])
|
19
|
+
assert_equal 0, @filters.size([])
|
20
|
+
assert_equal 0, @filters.size(nil)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_downcase
|
24
|
+
assert_equal 'testing', @filters.downcase("Testing")
|
25
|
+
assert_equal '', @filters.downcase(nil)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_upcase
|
29
|
+
assert_equal 'TESTING', @filters.upcase("Testing")
|
30
|
+
assert_equal '', @filters.upcase(nil)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_upcase
|
34
|
+
assert_equal 'TESTING', @filters.upcase("Testing")
|
35
|
+
assert_equal '', @filters.upcase(nil)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_truncate
|
39
|
+
assert_equal '1234...', @filters.truncate('1234567890', 7)
|
40
|
+
assert_equal '1234567890', @filters.truncate('1234567890', 20)
|
41
|
+
assert_equal '...', @filters.truncate('1234567890', 0)
|
42
|
+
assert_equal '1234567890', @filters.truncate('1234567890')
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_truncatewords
|
46
|
+
assert_equal 'one two three', @filters.truncatewords('one two three', 4)
|
47
|
+
assert_equal 'one two...', @filters.truncatewords('one two three', 2)
|
48
|
+
assert_equal 'one two three', @filters.truncatewords('one two three')
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_strip_html
|
52
|
+
assert_equal 'test', @filters.strip_html("<div>test</div>")
|
53
|
+
assert_equal 'test', @filters.strip_html("<div id='test'>test</div>")
|
54
|
+
assert_equal '', @filters.strip_html(nil)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_join
|
58
|
+
assert_equal '1 2 3 4', @filters.join([1,2,3,4])
|
59
|
+
assert_equal '1 - 2 - 3 - 4', @filters.join([1,2,3,4], ' - ')
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_sort
|
63
|
+
assert_equal [1,2,3,4], @filters.sort([4,3,2,1])
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_date
|
67
|
+
assert_equal 'May', @filters.date(Time.parse("2006-05-05 10:00:00"), "%B")
|
68
|
+
assert_equal 'June', @filters.date(Time.parse("2006-06-05 10:00:00"), "%B")
|
69
|
+
assert_equal 'July', @filters.date(Time.parse("2006-07-05 10:00:00"), "%B")
|
70
|
+
|
71
|
+
assert_equal 'May', @filters.date("2006-05-05 10:00:00", "%B")
|
72
|
+
assert_equal 'June', @filters.date("2006-06-05 10:00:00", "%B")
|
73
|
+
assert_equal 'July', @filters.date("2006-07-05 10:00:00", "%B")
|
74
|
+
|
75
|
+
assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", "")
|
76
|
+
assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", "")
|
77
|
+
assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", "")
|
78
|
+
assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", nil)
|
79
|
+
|
80
|
+
assert_equal '07/05/2006', @filters.date("2006-07-05 10:00:00", "%m/%d/%Y")
|
81
|
+
assert_equal nil, @filters.date(nil, "%B")
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
def test_first_last
|
86
|
+
assert_equal 1, @filters.first([1,2,3])
|
87
|
+
assert_equal 3, @filters.last([1,2,3])
|
88
|
+
assert_equal nil, @filters.first([])
|
89
|
+
assert_equal nil, @filters.last([])
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
end
|
101
|
+
|
@@ -0,0 +1,336 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
|
4
|
+
class TemplateTest < Test::Unit::TestCase
|
5
|
+
include Liquid
|
6
|
+
|
7
|
+
|
8
|
+
def test_tag
|
9
|
+
tag = Tag.new([], [])
|
10
|
+
assert_equal 'liquid::tag', tag.name
|
11
|
+
assert_equal '', tag.render(Context.new(Liquid::Template.new))
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_no_transform
|
15
|
+
assert_template_result('this text should come out of the template without change...',
|
16
|
+
'this text should come out of the template without change...')
|
17
|
+
assert_template_result('blah','blah')
|
18
|
+
assert_template_result('<blah>','<blah>')
|
19
|
+
assert_template_result('|,.:','|,.:')
|
20
|
+
assert_template_result('','')
|
21
|
+
|
22
|
+
text = %|this shouldnt see any transformation either but has multiple lines
|
23
|
+
as you can clearly see here ...|
|
24
|
+
assert_template_result(text,text)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_has_a_block_which_does_nothing
|
28
|
+
assert_template_result(%|the comment block should be removed .. right?|,
|
29
|
+
%|the comment block should be removed {%comment%} be gone.. {%endcomment%} .. right?|)
|
30
|
+
|
31
|
+
assert_template_result('','{%comment%}{%endcomment%}')
|
32
|
+
assert_template_result('','{%comment%}{% endcomment %}')
|
33
|
+
assert_template_result('','{% comment %}{%endcomment%}')
|
34
|
+
assert_template_result('','{% comment %}{% endcomment %}')
|
35
|
+
assert_template_result('','{%comment%}comment{%endcomment%}')
|
36
|
+
assert_template_result('','{% comment %}comment{% endcomment %}')
|
37
|
+
|
38
|
+
assert_template_result('foobar','foo{%comment%}comment{%endcomment%}bar')
|
39
|
+
assert_template_result('foobar','foo{% comment %}comment{% endcomment %}bar')
|
40
|
+
assert_template_result('foobar','foo{%comment%} comment {%endcomment%}bar')
|
41
|
+
assert_template_result('foobar','foo{% comment %} comment {% endcomment %}bar')
|
42
|
+
|
43
|
+
assert_template_result('foo bar','foo {%comment%} {%endcomment%} bar')
|
44
|
+
assert_template_result('foo bar','foo {%comment%}comment{%endcomment%} bar')
|
45
|
+
assert_template_result('foo bar','foo {%comment%} comment {%endcomment%} bar')
|
46
|
+
|
47
|
+
assert_template_result('foobar','foo{%comment%}
|
48
|
+
{%endcomment%}bar')
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_for
|
52
|
+
assert_template_result(' yo yo yo yo ','{%for item in array%} yo {%endfor%}','array' => [1,2,3,4])
|
53
|
+
assert_template_result('yoyo','{%for item in array%}yo{%endfor%}','array' => [1,2])
|
54
|
+
assert_template_result(' yo ','{%for item in array%} yo {%endfor%}','array' => [1])
|
55
|
+
assert_template_result('','{%for item in array%}{%endfor%}','array' => [1,2])
|
56
|
+
expected = <<HERE
|
57
|
+
|
58
|
+
yo
|
59
|
+
|
60
|
+
yo
|
61
|
+
|
62
|
+
yo
|
63
|
+
|
64
|
+
HERE
|
65
|
+
template = <<HERE
|
66
|
+
{%for item in array%}
|
67
|
+
yo
|
68
|
+
{%endfor%}
|
69
|
+
HERE
|
70
|
+
assert_template_result(expected,template,'array' => [1,2,3])
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_for_with_variable
|
74
|
+
assert_template_result(' 1 2 3 ','{%for item in array%} {{item}} {%endfor%}','array' => [1,2,3])
|
75
|
+
assert_template_result('123','{%for item in array%}{{item}}{%endfor%}','array' => [1,2,3])
|
76
|
+
assert_template_result('123','{% for item in array %}{{item}}{% endfor %}','array' => [1,2,3])
|
77
|
+
assert_template_result('abcd','{%for item in array%}{{item}}{%endfor%}','array' => ['a','b','c','d'])
|
78
|
+
assert_template_result('a b c','{%for item in array%}{{item}}{%endfor%}','array' => ['a',' ','b',' ','c'])
|
79
|
+
assert_template_result('abc','{%for item in array%}{{item}}{%endfor%}','array' => ['a','','b','','c'])
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_for_helpers
|
83
|
+
assigns = {'array' => [1,2,3] }
|
84
|
+
assert_template_result(' 1/3 2/3 3/3 ','{%for item in array%} {{forloop.index}}/{{forloop.length}} {%endfor%}',assigns)
|
85
|
+
assert_template_result(' 1 2 3 ','{%for item in array%} {{forloop.index}} {%endfor%}',assigns)
|
86
|
+
assert_template_result(' 0 1 2 ','{%for item in array%} {{forloop.index0}} {%endfor%}',assigns)
|
87
|
+
assert_template_result(' 2 1 0 ','{%for item in array%} {{forloop.rindex0}} {%endfor%}',assigns)
|
88
|
+
assert_template_result(' 3 2 1 ','{%for item in array%} {{forloop.rindex}} {%endfor%}',assigns)
|
89
|
+
assert_template_result(' true false false ','{%for item in array%} {{forloop.first}} {%endfor%}',assigns)
|
90
|
+
assert_template_result(' false false true ','{%for item in array%} {{forloop.last}} {%endfor%}',assigns)
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_for_and_if
|
94
|
+
assigns = {'array' => [1,2,3] }
|
95
|
+
assert_template_result(' yay ',
|
96
|
+
'{%for item in array%} {% if forloop.first %}yay{% endif %} {%endfor%}',
|
97
|
+
assigns)
|
98
|
+
assert_template_result(' yay boo boo ',
|
99
|
+
'{%for item in array%} {% if forloop.first %}yay{% else %}boo{% endif %} {%endfor%}',
|
100
|
+
assigns)
|
101
|
+
assert_template_result(' boo boo ',
|
102
|
+
'{%for item in array%} {% if forloop.first %}{% else %}boo{% endif %} {%endfor%}',
|
103
|
+
assigns)
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_limiting
|
107
|
+
assigns = {'array' => [1,2,3,4,5,6,7,8,9,0]}
|
108
|
+
assert_template_result('12','{%for i in array limit:2 %}{{ i }}{%endfor%}',assigns)
|
109
|
+
assert_template_result('1234','{%for i in array limit:4 %}{{ i }}{%endfor%}',assigns)
|
110
|
+
assert_template_result('3456','{%for i in array limit:4 offset:2 %}{{ i }}{%endfor%}',assigns)
|
111
|
+
assert_template_result('3456','{%for i in array limit: 4 offset: 2 %}{{ i }}{%endfor%}',assigns)
|
112
|
+
|
113
|
+
assigns['limit'] = 2
|
114
|
+
assigns['offset'] = 2
|
115
|
+
assert_template_result('34','{%for i in array limit: limit offset: offset %}{{ i }}{%endfor%}',assigns)
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_nested_for
|
119
|
+
assigns = {'array' => [[1,2],[3,4],[5,6]] }
|
120
|
+
assert_template_result('123456','{%for item in array%}{%for i in item%}{{ i }}{%endfor%}{%endfor%}',assigns)
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_offset_only
|
124
|
+
assigns = {'array' => [1,2,3,4,5,6,7,8,9,0]}
|
125
|
+
assert_template_result('890','{%for i in array offset:7 %}{{ i }}{%endfor%}',assigns)
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_pause_resume
|
129
|
+
assigns = {'array' => {'items' => [1,2,3,4,5,6,7,8,9,0]}}
|
130
|
+
markup = <<-MKUP
|
131
|
+
{%for i in array.items limit: 3 %}{{i}}{%endfor%}
|
132
|
+
next
|
133
|
+
{%for i in array.items offset:continue limit: 3 %}{{i}}{%endfor%}
|
134
|
+
next
|
135
|
+
{%for i in array.items offset:continue limit: 3 %}{{i}}{%endfor%}
|
136
|
+
MKUP
|
137
|
+
expected = <<-XPCTD
|
138
|
+
123
|
139
|
+
next
|
140
|
+
456
|
141
|
+
next
|
142
|
+
789
|
143
|
+
XPCTD
|
144
|
+
assert_template_result(expected,markup,assigns)
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_pause_resume_limit
|
148
|
+
assigns = {'array' => {'items' => [1,2,3,4,5,6,7,8,9,0]}}
|
149
|
+
markup = <<-MKUP
|
150
|
+
{%for i in array.items limit:3 %}{{i}}{%endfor%}
|
151
|
+
next
|
152
|
+
{%for i in array.items offset:continue limit:3 %}{{i}}{%endfor%}
|
153
|
+
next
|
154
|
+
{%for i in array.items offset:continue limit:1 %}{{i}}{%endfor%}
|
155
|
+
MKUP
|
156
|
+
expected = <<-XPCTD
|
157
|
+
123
|
158
|
+
next
|
159
|
+
456
|
160
|
+
next
|
161
|
+
7
|
162
|
+
XPCTD
|
163
|
+
assert_template_result(expected,markup,assigns)
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_pause_resume_BIG_limit
|
167
|
+
assigns = {'array' => {'items' => [1,2,3,4,5,6,7,8,9,0]}}
|
168
|
+
markup = <<-MKUP
|
169
|
+
{%for i in array.items limit:3 %}{{i}}{%endfor%}
|
170
|
+
next
|
171
|
+
{%for i in array.items offset:continue limit:3 %}{{i}}{%endfor%}
|
172
|
+
next
|
173
|
+
{%for i in array.items offset:continue limit:1000 %}{{i}}{%endfor%}
|
174
|
+
MKUP
|
175
|
+
expected = <<-XPCTD
|
176
|
+
123
|
177
|
+
next
|
178
|
+
456
|
179
|
+
next
|
180
|
+
7890
|
181
|
+
XPCTD
|
182
|
+
assert_template_result(expected,markup,assigns)
|
183
|
+
end
|
184
|
+
|
185
|
+
|
186
|
+
def test_pause_resume_BIG_offset
|
187
|
+
assigns = {'array' => {'items' => [1,2,3,4,5,6,7,8,9,0]}}
|
188
|
+
markup = <<-MKUP
|
189
|
+
{%for i in array.items limit:3 %}{{i}}{%endfor%}
|
190
|
+
next
|
191
|
+
{%for i in array.items offset:continue limit:3 %}{{i}}{%endfor%}
|
192
|
+
next
|
193
|
+
{%for i in array.items offset:continue limit:3 offset:1000 %}{{i}}{%endfor%}
|
194
|
+
MKUP
|
195
|
+
expected = <<-XPCTD
|
196
|
+
123
|
197
|
+
next
|
198
|
+
456
|
199
|
+
next
|
200
|
+
|
201
|
+
XPCTD
|
202
|
+
assert_template_result(expected,markup,assigns)
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_assign
|
206
|
+
assigns = {'var' => 'content' }
|
207
|
+
assert_template_result('var2: var2:content','var2:{{var2}} {%assign var2 = var%} var2:{{var2}}',assigns)
|
208
|
+
|
209
|
+
end
|
210
|
+
|
211
|
+
def test_capture
|
212
|
+
assigns = {'var' => 'content' }
|
213
|
+
assert_template_result('content foo content foo ','{{ var2 }}{% capture var2 %}{{ var }} foo {% endcapture %}{{ var2 }}{{ var2 }}', assigns)
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_capture_detects_bad_syntax
|
217
|
+
assert_raise(SyntaxError) do
|
218
|
+
assert_template_result('content foo content foo ','{{ var2 }}{% capture %}{{ var }} foo {% endcapture %}{{ var2 }}{{ var2 }}', {'var' => 'content' })
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def test_case
|
223
|
+
assigns = {'condition' => 2 }
|
224
|
+
assert_template_result(' its 2 ','{% case condition %}{% when 1 %} its 1 {% when 2 %} its 2 {% endcase %}', assigns)
|
225
|
+
|
226
|
+
assigns = {'condition' => 1 }
|
227
|
+
assert_template_result(' its 1 ','{% case condition %}{% when 1 %} its 1 {% when 2 %} its 2 {% endcase %}', assigns)
|
228
|
+
|
229
|
+
assigns = {'condition' => 3 }
|
230
|
+
assert_template_result('','{% case condition %}{% when 1 %} its 1 {% when 2 %} its 2 {% endcase %}', assigns)
|
231
|
+
|
232
|
+
assigns = {'condition' => "string here" }
|
233
|
+
assert_template_result(' hit ','{% case condition %}{% when "string here" %} hit {% endcase %}', assigns)
|
234
|
+
|
235
|
+
assigns = {'condition' => "bad string here" }
|
236
|
+
assert_template_result('','{% case condition %}{% when "string here" %} hit {% endcase %}', assigns)
|
237
|
+
end
|
238
|
+
|
239
|
+
def test_case_with_else
|
240
|
+
|
241
|
+
assigns = {'condition' => 5 }
|
242
|
+
assert_template_result(' hit ','{% case condition %}{% when 5 %} hit {% else %} else {% endcase %}', assigns)
|
243
|
+
|
244
|
+
assigns = {'condition' => 6 }
|
245
|
+
assert_template_result(' else ','{% case condition %}{% when 5 %} hit {% else %} else {% endcase %}', assigns)
|
246
|
+
|
247
|
+
assigns = {'condition' => 6 }
|
248
|
+
assert_template_result(' else ','{% case condition %} {% when 5 %} hit {% else %} else {% endcase %}', assigns)
|
249
|
+
|
250
|
+
|
251
|
+
end
|
252
|
+
|
253
|
+
def test_case_on_size
|
254
|
+
assert_template_result('', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [])
|
255
|
+
assert_template_result('1' , '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1])
|
256
|
+
assert_template_result('2' , '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1, 1])
|
257
|
+
assert_template_result('', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1, 1, 1])
|
258
|
+
assert_template_result('', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1, 1, 1, 1])
|
259
|
+
assert_template_result('', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1, 1, 1, 1, 1])
|
260
|
+
end
|
261
|
+
|
262
|
+
def test_case_on_size_with_else
|
263
|
+
assert_template_result('else', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}', 'a' => [])
|
264
|
+
assert_template_result('1', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}', 'a' => [1])
|
265
|
+
assert_template_result('2', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}', 'a' => [1, 1])
|
266
|
+
assert_template_result('else', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}', 'a' => [1, 1, 1])
|
267
|
+
assert_template_result('else', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}', 'a' => [1, 1, 1, 1])
|
268
|
+
assert_template_result('else', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}', 'a' => [1, 1, 1, 1, 1])
|
269
|
+
end
|
270
|
+
|
271
|
+
def test_case_on_length_with_else
|
272
|
+
assert_template_result('else', '{% case a.empty? %}{% when true %}true{% when false %}false{% else %}else{% endcase %}', {})
|
273
|
+
assert_template_result('false', '{% case false %}{% when true %}true{% when false %}false{% else %}else{% endcase %}', {})
|
274
|
+
assert_template_result('true', '{% case true %}{% when true %}true{% when false %}false{% else %}else{% endcase %}', {})
|
275
|
+
assert_template_result('else', '{% case NULL %}{% when true %}true{% when false %}false{% else %}else{% endcase %}', {})
|
276
|
+
end
|
277
|
+
|
278
|
+
def test_case_detects_bad_syntax
|
279
|
+
assert_raise(SyntaxError) do
|
280
|
+
assert_template_result('', '{% case false %}{% when %}true{% endcase %}', {})
|
281
|
+
end
|
282
|
+
|
283
|
+
assert_raise(SyntaxError) do
|
284
|
+
assert_template_result('', '{% case false %}{% huh %}true{% endcase %}', {})
|
285
|
+
end
|
286
|
+
|
287
|
+
end
|
288
|
+
|
289
|
+
|
290
|
+
|
291
|
+
def test_cycle
|
292
|
+
|
293
|
+
assert_template_result('one','{%cycle "one", "two"%}')
|
294
|
+
assert_template_result('one two','{%cycle "one", "two"%} {%cycle "one", "two"%}')
|
295
|
+
|
296
|
+
assert_template_result('one two one','{%cycle "one", "two"%} {%cycle "one", "two"%} {%cycle "one", "two"%}')
|
297
|
+
end
|
298
|
+
|
299
|
+
def test_multiple_cycles
|
300
|
+
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%}')
|
301
|
+
end
|
302
|
+
|
303
|
+
def test_multiple_named_cycles
|
304
|
+
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" %}')
|
305
|
+
end
|
306
|
+
|
307
|
+
def test_multiple_named_cycles_with_names_from_context
|
308
|
+
assigns = {"var1" => 1, "var2" => 2 }
|
309
|
+
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)
|
310
|
+
end
|
311
|
+
|
312
|
+
def test_size_of_array
|
313
|
+
assigns = {"array" => [1,2,3,4]}
|
314
|
+
assert_template_result('array has 4 elements', "array has {{ array.size }} elements", assigns)
|
315
|
+
end
|
316
|
+
|
317
|
+
def test_size_of_hash
|
318
|
+
assigns = {"hash" => {:a => 1, :b => 2, :c=> 3, :d => 4}}
|
319
|
+
assert_template_result('hash has 4 elements', "hash has {{ hash.size }} elements", assigns)
|
320
|
+
end
|
321
|
+
|
322
|
+
def test_illegal_symbols
|
323
|
+
assert_template_result('', '{% if true == empty %}?{% endif %}', {})
|
324
|
+
assert_template_result('', '{% if true == null %}?{% endif %}', {})
|
325
|
+
assert_template_result('', '{% if empty == true %}?{% endif %}', {})
|
326
|
+
assert_template_result('', '{% if null == true %}?{% endif %}', {})
|
327
|
+
end
|
328
|
+
|
329
|
+
def test_ifchanged
|
330
|
+
assigns = {'array' => [ 1, 1, 2, 2, 3, 3] }
|
331
|
+
assert_template_result('123','{%for item in array%}{%ifchanged%}{{item}}{% endifchanged %}{%endfor%}',assigns)
|
332
|
+
|
333
|
+
assigns = {'array' => [ 1, 1, 1, 1] }
|
334
|
+
assert_template_result('1','{%for item in array%}{%ifchanged%}{{item}}{% endifchanged %}{%endfor%}',assigns)
|
335
|
+
end
|
336
|
+
end
|