wordify_liquid 2.5.1

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.
Files changed (69) hide show
  1. data/History.md +75 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +44 -0
  4. data/lib/extras/liquid_view.rb +51 -0
  5. data/lib/liquid.rb +68 -0
  6. data/lib/liquid/block.rb +115 -0
  7. data/lib/liquid/condition.rb +120 -0
  8. data/lib/liquid/context.rb +259 -0
  9. data/lib/liquid/document.rb +17 -0
  10. data/lib/liquid/drop.rb +61 -0
  11. data/lib/liquid/errors.rb +11 -0
  12. data/lib/liquid/extensions.rb +62 -0
  13. data/lib/liquid/file_system.rb +62 -0
  14. data/lib/liquid/htmltags.rb +74 -0
  15. data/lib/liquid/interrupts.rb +17 -0
  16. data/lib/liquid/module_ex.rb +62 -0
  17. data/lib/liquid/standardfilters.rb +245 -0
  18. data/lib/liquid/strainer.rb +53 -0
  19. data/lib/liquid/tag.rb +26 -0
  20. data/lib/liquid/tags/assign.rb +33 -0
  21. data/lib/liquid/tags/break.rb +21 -0
  22. data/lib/liquid/tags/capture.rb +35 -0
  23. data/lib/liquid/tags/case.rb +79 -0
  24. data/lib/liquid/tags/comment.rb +9 -0
  25. data/lib/liquid/tags/continue.rb +21 -0
  26. data/lib/liquid/tags/cycle.rb +59 -0
  27. data/lib/liquid/tags/decrement.rb +39 -0
  28. data/lib/liquid/tags/for.rb +142 -0
  29. data/lib/liquid/tags/if.rb +79 -0
  30. data/lib/liquid/tags/ifchanged.rb +20 -0
  31. data/lib/liquid/tags/include.rb +65 -0
  32. data/lib/liquid/tags/increment.rb +35 -0
  33. data/lib/liquid/tags/raw.rb +21 -0
  34. data/lib/liquid/tags/unless.rb +33 -0
  35. data/lib/liquid/template.rb +150 -0
  36. data/lib/liquid/utils.rb +31 -0
  37. data/lib/liquid/variable.rb +57 -0
  38. data/lib/wordify_liquid.rb +1 -0
  39. data/test/liquid/assign_test.rb +21 -0
  40. data/test/liquid/block_test.rb +58 -0
  41. data/test/liquid/capture_test.rb +40 -0
  42. data/test/liquid/condition_test.rb +127 -0
  43. data/test/liquid/context_test.rb +478 -0
  44. data/test/liquid/drop_test.rb +169 -0
  45. data/test/liquid/error_handling_test.rb +81 -0
  46. data/test/liquid/file_system_test.rb +29 -0
  47. data/test/liquid/filter_test.rb +125 -0
  48. data/test/liquid/module_ex_test.rb +87 -0
  49. data/test/liquid/output_test.rb +116 -0
  50. data/test/liquid/parsing_quirks_test.rb +52 -0
  51. data/test/liquid/regexp_test.rb +44 -0
  52. data/test/liquid/security_test.rb +64 -0
  53. data/test/liquid/standard_filter_test.rb +195 -0
  54. data/test/liquid/strainer_test.rb +52 -0
  55. data/test/liquid/tags/break_tag_test.rb +16 -0
  56. data/test/liquid/tags/continue_tag_test.rb +16 -0
  57. data/test/liquid/tags/for_tag_test.rb +284 -0
  58. data/test/liquid/tags/html_tag_test.rb +63 -0
  59. data/test/liquid/tags/if_else_tag_test.rb +160 -0
  60. data/test/liquid/tags/include_tag_test.rb +139 -0
  61. data/test/liquid/tags/increment_tag_test.rb +24 -0
  62. data/test/liquid/tags/raw_tag_test.rb +15 -0
  63. data/test/liquid/tags/standard_tag_test.rb +295 -0
  64. data/test/liquid/tags/statements_test.rb +134 -0
  65. data/test/liquid/tags/unless_else_tag_test.rb +26 -0
  66. data/test/liquid/template_test.rb +74 -0
  67. data/test/liquid/variable_test.rb +180 -0
  68. data/test/test_helper.rb +29 -0
  69. metadata +145 -0
@@ -0,0 +1,139 @@
1
+ require 'test_helper'
2
+
3
+ class TestFileSystem
4
+ def read_template_file(template_path, context)
5
+ case template_path
6
+ when "product"
7
+ "Product: {{ product.title }} "
8
+
9
+ when "locale_variables"
10
+ "Locale: {{echo1}} {{echo2}}"
11
+
12
+ when "variant"
13
+ "Variant: {{ variant.title }}"
14
+
15
+ when "nested_template"
16
+ "{% include 'header' %} {% include 'body' %} {% include 'footer' %}"
17
+
18
+ when "body"
19
+ "body {% include 'body_detail' %}"
20
+
21
+ when "nested_product_template"
22
+ "Product: {{ nested_product_template.title }} {%include 'details'%} "
23
+
24
+ when "recursively_nested_template"
25
+ "-{% include 'recursively_nested_template' %}"
26
+
27
+ when "pick_a_source"
28
+ "from TestFileSystem"
29
+
30
+ else
31
+ template_path
32
+ end
33
+ end
34
+ end
35
+
36
+ class OtherFileSystem
37
+ def read_template_file(template_path, context)
38
+ 'from OtherFileSystem'
39
+ end
40
+ end
41
+
42
+ class IncludeTagTest < Test::Unit::TestCase
43
+ include Liquid
44
+
45
+ def setup
46
+ Liquid::Template.file_system = TestFileSystem.new
47
+ end
48
+
49
+ def test_include_tag_looks_for_file_system_in_registers_first
50
+ assert_equal 'from OtherFileSystem',
51
+ Template.parse("{% include 'pick_a_source' %}").render({}, :registers => {:file_system => OtherFileSystem.new})
52
+ end
53
+
54
+
55
+ def test_include_tag_with
56
+ assert_equal "Product: Draft 151cm ",
57
+ Template.parse("{% include 'product' with products[0] %}").render( "products" => [ {'title' => 'Draft 151cm'}, {'title' => 'Element 155cm'} ] )
58
+ end
59
+
60
+ def test_include_tag_with_default_name
61
+ assert_equal "Product: Draft 151cm ",
62
+ Template.parse("{% include 'product' %}").render( "product" => {'title' => 'Draft 151cm'} )
63
+ end
64
+
65
+ def test_include_tag_for
66
+
67
+ assert_equal "Product: Draft 151cm Product: Element 155cm ",
68
+ Template.parse("{% include 'product' for products %}").render( "products" => [ {'title' => 'Draft 151cm'}, {'title' => 'Element 155cm'} ] )
69
+ end
70
+
71
+ def test_include_tag_with_local_variables
72
+ assert_equal "Locale: test123 ",
73
+ Template.parse("{% include 'locale_variables' echo1: 'test123' %}").render
74
+ end
75
+
76
+ def test_include_tag_with_multiple_local_variables
77
+ assert_equal "Locale: test123 test321",
78
+ Template.parse("{% include 'locale_variables' echo1: 'test123', echo2: 'test321' %}").render
79
+ end
80
+
81
+ def test_include_tag_with_multiple_local_variables_from_context
82
+ assert_equal "Locale: test123 test321",
83
+ Template.parse("{% include 'locale_variables' echo1: echo1, echo2: more_echos.echo2 %}").render('echo1' => 'test123', 'more_echos' => { "echo2" => 'test321'})
84
+ end
85
+
86
+ def test_nested_include_tag
87
+ assert_equal "body body_detail",
88
+ Template.parse("{% include 'body' %}").render
89
+
90
+ assert_equal "header body body_detail footer",
91
+ Template.parse("{% include 'nested_template' %}").render
92
+ end
93
+
94
+ def test_nested_include_with_variable
95
+
96
+ assert_equal "Product: Draft 151cm details ",
97
+ Template.parse("{% include 'nested_product_template' with product %}").render("product" => {"title" => 'Draft 151cm'})
98
+
99
+ assert_equal "Product: Draft 151cm details Product: Element 155cm details ",
100
+ Template.parse("{% include 'nested_product_template' for products %}").render("products" => [{"title" => 'Draft 151cm'}, {"title" => 'Element 155cm'}])
101
+
102
+ end
103
+
104
+ def test_recursively_included_template_does_not_produce_endless_loop
105
+
106
+ infinite_file_system = Class.new do
107
+ def read_template_file(template_path, context)
108
+ "-{% include 'loop' %}"
109
+ end
110
+ end
111
+
112
+ Liquid::Template.file_system = infinite_file_system.new
113
+
114
+ assert_raise(Liquid::StackLevelError) do
115
+ Template.parse("{% include 'loop' %}").render!
116
+ end
117
+
118
+ end
119
+
120
+ def test_backwards_compatability_support_for_overridden_read_template_file
121
+ infinite_file_system = Class.new do
122
+ def read_template_file(template_path) # testing only one argument here.
123
+ "- hi mom"
124
+ end
125
+ end
126
+
127
+ Liquid::Template.file_system = infinite_file_system.new
128
+
129
+ Template.parse("{% include 'hi_mom' %}").render!
130
+ end
131
+
132
+ def test_dynamically_choosen_template
133
+
134
+ assert_equal "Test123", Template.parse("{% include template %}").render("template" => 'Test123')
135
+ assert_equal "Test321", Template.parse("{% include template %}").render("template" => 'Test321')
136
+
137
+ assert_equal "Product: Draft 151cm ", Template.parse("{% include template for product %}").render("template" => 'product', 'product' => { 'title' => 'Draft 151cm'})
138
+ end
139
+ end # IncludeTagTest
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+
3
+ class IncrementTagTest < Test::Unit::TestCase
4
+ include Liquid
5
+
6
+ def test_inc
7
+ assert_template_result('0','{%increment port %}', {})
8
+ assert_template_result('0 1','{%increment port %} {%increment port%}', {})
9
+ assert_template_result('0 0 1 2 1',
10
+ '{%increment port %} {%increment starboard%} ' +
11
+ '{%increment port %} {%increment port%} ' +
12
+ '{%increment starboard %}', {})
13
+ end
14
+
15
+ def test_dec
16
+ assert_template_result('9','{%decrement port %}', { 'port' => 10})
17
+ assert_template_result('-1 -2','{%decrement port %} {%decrement port%}', {})
18
+ assert_template_result('1 5 2 2 5',
19
+ '{%increment port %} {%increment starboard%} ' +
20
+ '{%increment port %} {%decrement port%} ' +
21
+ '{%decrement starboard %}', { 'port' => 1, 'starboard' => 5 })
22
+ end
23
+
24
+ end
@@ -0,0 +1,15 @@
1
+ require 'test_helper'
2
+
3
+ class RawTagTest < Test::Unit::TestCase
4
+ include Liquid
5
+
6
+ def test_tag_in_raw
7
+ assert_template_result '{% comment %} test {% endcomment %}',
8
+ '{% raw %}{% comment %} test {% endcomment %}{% endraw %}'
9
+ end
10
+
11
+ def test_output_in_raw
12
+ assert_template_result '{{ test }}',
13
+ '{% raw %}{{ test }}{% endraw %}'
14
+ end
15
+ end
@@ -0,0 +1,295 @@
1
+ require 'test_helper'
2
+
3
+ class StandardTagTest < Test::Unit::TestCase
4
+ include Liquid
5
+
6
+ def test_tag
7
+ tag = Tag.new('tag', [], [])
8
+ assert_equal 'liquid::tag', tag.name
9
+ assert_equal '', tag.render(Context.new)
10
+ end
11
+
12
+ def test_no_transform
13
+ assert_template_result('this text should come out of the template without change...',
14
+ 'this text should come out of the template without change...')
15
+
16
+ assert_template_result('blah','blah')
17
+ assert_template_result('<blah>','<blah>')
18
+ assert_template_result('|,.:','|,.:')
19
+ assert_template_result('','')
20
+
21
+ text = %|this shouldnt see any transformation either but has multiple lines
22
+ as you can clearly see here ...|
23
+ assert_template_result(text,text)
24
+ end
25
+
26
+ def test_has_a_block_which_does_nothing
27
+ assert_template_result(%|the comment block should be removed .. right?|,
28
+ %|the comment block should be removed {%comment%} be gone.. {%endcomment%} .. right?|)
29
+
30
+ assert_template_result('','{%comment%}{%endcomment%}')
31
+ assert_template_result('','{%comment%}{% endcomment %}')
32
+ assert_template_result('','{% comment %}{%endcomment%}')
33
+ assert_template_result('','{% comment %}{% endcomment %}')
34
+ assert_template_result('','{%comment%}comment{%endcomment%}')
35
+ assert_template_result('','{% comment %}comment{% endcomment %}')
36
+
37
+ assert_template_result('foobar','foo{%comment%}comment{%endcomment%}bar')
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
+
42
+ assert_template_result('foo bar','foo {%comment%} {%endcomment%} bar')
43
+ assert_template_result('foo bar','foo {%comment%}comment{%endcomment%} bar')
44
+ assert_template_result('foo bar','foo {%comment%} comment {%endcomment%} bar')
45
+
46
+ assert_template_result('foobar','foo{%comment%}
47
+ {%endcomment%}bar')
48
+ end
49
+
50
+ def test_assign
51
+ assigns = {'var' => 'content' }
52
+ assert_template_result('var2: var2:content', 'var2:{{var2}} {%assign var2 = var%} var2:{{var2}}', assigns)
53
+
54
+ end
55
+
56
+ def test_hyphenated_assign
57
+ assigns = {'a-b' => '1' }
58
+ assert_template_result('a-b:1 a-b:2', 'a-b:{{a-b}} {%assign a-b = 2 %}a-b:{{a-b}}', assigns)
59
+
60
+ end
61
+
62
+ def test_assign_with_colon_and_spaces
63
+ assigns = {'var' => {'a:b c' => {'paged' => '1' }}}
64
+ assert_template_result('var2: 1', '{%assign var2 = var["a:b c"].paged %}var2: {{var2}}', assigns)
65
+ end
66
+
67
+ def test_capture
68
+ assigns = {'var' => 'content' }
69
+ assert_template_result('content foo content foo ',
70
+ '{{ var2 }}{% capture var2 %}{{ var }} foo {% endcapture %}{{ var2 }}{{ var2 }}',
71
+ assigns)
72
+ end
73
+
74
+ def test_capture_detects_bad_syntax
75
+ assert_raise(SyntaxError) do
76
+ assert_template_result('content foo content foo ',
77
+ '{{ var2 }}{% capture %}{{ var }} foo {% endcapture %}{{ var2 }}{{ var2 }}',
78
+ {'var' => 'content' })
79
+ end
80
+ end
81
+
82
+ def test_case
83
+ assigns = {'condition' => 2 }
84
+ assert_template_result(' its 2 ',
85
+ '{% case condition %}{% when 1 %} its 1 {% when 2 %} its 2 {% endcase %}',
86
+ assigns)
87
+
88
+ assigns = {'condition' => 1 }
89
+ assert_template_result(' its 1 ',
90
+ '{% case condition %}{% when 1 %} its 1 {% when 2 %} its 2 {% endcase %}',
91
+ assigns)
92
+
93
+ assigns = {'condition' => 3 }
94
+ assert_template_result('',
95
+ '{% case condition %}{% when 1 %} its 1 {% when 2 %} its 2 {% endcase %}',
96
+ assigns)
97
+
98
+ assigns = {'condition' => "string here" }
99
+ assert_template_result(' hit ',
100
+ '{% case condition %}{% when "string here" %} hit {% endcase %}',
101
+ assigns)
102
+
103
+ assigns = {'condition' => "bad string here" }
104
+ assert_template_result('',
105
+ '{% case condition %}{% when "string here" %} hit {% endcase %}',\
106
+ assigns)
107
+ end
108
+
109
+ def test_case_with_else
110
+ assigns = {'condition' => 5 }
111
+ assert_template_result(' hit ',
112
+ '{% case condition %}{% when 5 %} hit {% else %} else {% endcase %}',
113
+ assigns)
114
+
115
+ assigns = {'condition' => 6 }
116
+ assert_template_result(' else ',
117
+ '{% case condition %}{% when 5 %} hit {% else %} else {% endcase %}',
118
+ assigns)
119
+
120
+ assigns = {'condition' => 6 }
121
+ assert_template_result(' else ',
122
+ '{% case condition %} {% when 5 %} hit {% else %} else {% endcase %}',
123
+ assigns)
124
+ end
125
+
126
+ def test_case_on_size
127
+ assert_template_result('', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [])
128
+ assert_template_result('1', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1])
129
+ assert_template_result('2', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1, 1])
130
+ assert_template_result('', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1, 1, 1])
131
+ assert_template_result('', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1, 1, 1, 1])
132
+ assert_template_result('', '{% case a.size %}{% when 1 %}1{% when 2 %}2{% endcase %}', 'a' => [1, 1, 1, 1, 1])
133
+ end
134
+
135
+ def test_case_on_size_with_else
136
+ assert_template_result('else',
137
+ '{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}',
138
+ 'a' => [])
139
+
140
+ assert_template_result('1',
141
+ '{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}',
142
+ 'a' => [1])
143
+
144
+ assert_template_result('2',
145
+ '{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}',
146
+ 'a' => [1, 1])
147
+
148
+ assert_template_result('else',
149
+ '{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}',
150
+ 'a' => [1, 1, 1])
151
+
152
+ assert_template_result('else',
153
+ '{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}',
154
+ 'a' => [1, 1, 1, 1])
155
+
156
+ assert_template_result('else',
157
+ '{% case a.size %}{% when 1 %}1{% when 2 %}2{% else %}else{% endcase %}',
158
+ 'a' => [1, 1, 1, 1, 1])
159
+ end
160
+
161
+ def test_case_on_length_with_else
162
+ assert_template_result('else',
163
+ '{% case a.empty? %}{% when true %}true{% when false %}false{% else %}else{% endcase %}',
164
+ {})
165
+
166
+ assert_template_result('false',
167
+ '{% case false %}{% when true %}true{% when false %}false{% else %}else{% endcase %}',
168
+ {})
169
+
170
+ assert_template_result('true',
171
+ '{% case true %}{% when true %}true{% when false %}false{% else %}else{% endcase %}',
172
+ {})
173
+
174
+ assert_template_result('else',
175
+ '{% case NULL %}{% when true %}true{% when false %}false{% else %}else{% endcase %}',
176
+ {})
177
+ end
178
+
179
+ def test_assign_from_case
180
+ # Example from the shopify forums
181
+ code = %q({% case collection.handle %}{% when 'menswear-jackets' %}{% assign ptitle = 'menswear' %}{% when 'menswear-t-shirts' %}{% assign ptitle = 'menswear' %}{% else %}{% assign ptitle = 'womenswear' %}{% endcase %}{{ ptitle }})
182
+ template = Liquid::Template.parse(code)
183
+ assert_equal "menswear", template.render("collection" => {'handle' => 'menswear-jackets'})
184
+ assert_equal "menswear", template.render("collection" => {'handle' => 'menswear-t-shirts'})
185
+ assert_equal "womenswear", template.render("collection" => {'handle' => 'x'})
186
+ assert_equal "womenswear", template.render("collection" => {'handle' => 'y'})
187
+ assert_equal "womenswear", template.render("collection" => {'handle' => 'z'})
188
+ end
189
+
190
+ def test_case_when_or
191
+ code = '{% case condition %}{% when 1 or 2 or 3 %} its 1 or 2 or 3 {% when 4 %} its 4 {% endcase %}'
192
+ assert_template_result(' its 1 or 2 or 3 ', code, {'condition' => 1 })
193
+ assert_template_result(' its 1 or 2 or 3 ', code, {'condition' => 2 })
194
+ assert_template_result(' its 1 or 2 or 3 ', code, {'condition' => 3 })
195
+ assert_template_result(' its 4 ', code, {'condition' => 4 })
196
+ assert_template_result('', code, {'condition' => 5 })
197
+
198
+ code = '{% case condition %}{% when 1 or "string" or null %} its 1 or 2 or 3 {% when 4 %} its 4 {% endcase %}'
199
+ assert_template_result(' its 1 or 2 or 3 ', code, {'condition' => 1 })
200
+ assert_template_result(' its 1 or 2 or 3 ', code, {'condition' => 'string' })
201
+ assert_template_result(' its 1 or 2 or 3 ', code, {'condition' => nil })
202
+ assert_template_result('', code, {'condition' => 'something else' })
203
+ end
204
+
205
+ def test_case_when_comma
206
+ code = '{% case condition %}{% when 1, 2, 3 %} its 1 or 2 or 3 {% when 4 %} its 4 {% endcase %}'
207
+ assert_template_result(' its 1 or 2 or 3 ', code, {'condition' => 1 })
208
+ assert_template_result(' its 1 or 2 or 3 ', code, {'condition' => 2 })
209
+ assert_template_result(' its 1 or 2 or 3 ', code, {'condition' => 3 })
210
+ assert_template_result(' its 4 ', code, {'condition' => 4 })
211
+ assert_template_result('', code, {'condition' => 5 })
212
+
213
+ code = '{% case condition %}{% when 1, "string", null %} its 1 or 2 or 3 {% when 4 %} its 4 {% endcase %}'
214
+ assert_template_result(' its 1 or 2 or 3 ', code, {'condition' => 1 })
215
+ assert_template_result(' its 1 or 2 or 3 ', code, {'condition' => 'string' })
216
+ assert_template_result(' its 1 or 2 or 3 ', code, {'condition' => nil })
217
+ assert_template_result('', code, {'condition' => 'something else' })
218
+ end
219
+
220
+ def test_assign
221
+ assert_equal 'variable', Liquid::Template.parse( '{% assign a = "variable"%}{{a}}' ).render
222
+ end
223
+
224
+ def test_assign_an_empty_string
225
+ assert_equal '', Liquid::Template.parse( '{% assign a = ""%}{{a}}' ).render
226
+ end
227
+
228
+ def test_assign_is_global
229
+ assert_equal 'variable',
230
+ Liquid::Template.parse( '{%for i in (1..2) %}{% assign a = "variable"%}{% endfor %}{{a}}' ).render
231
+ end
232
+
233
+ def test_case_detects_bad_syntax
234
+ assert_raise(SyntaxError) do
235
+ assert_template_result('', '{% case false %}{% when %}true{% endcase %}', {})
236
+ end
237
+
238
+ assert_raise(SyntaxError) do
239
+ assert_template_result('', '{% case false %}{% huh %}true{% endcase %}', {})
240
+ end
241
+
242
+ end
243
+
244
+ def test_cycle
245
+ assert_template_result('one','{%cycle "one", "two"%}')
246
+ assert_template_result('one two','{%cycle "one", "two"%} {%cycle "one", "two"%}')
247
+ assert_template_result(' two','{%cycle "", "two"%} {%cycle "", "two"%}')
248
+
249
+ assert_template_result('one two one','{%cycle "one", "two"%} {%cycle "one", "two"%} {%cycle "one", "two"%}')
250
+
251
+ assert_template_result('text-align: left text-align: right',
252
+ '{%cycle "text-align: left", "text-align: right" %} {%cycle "text-align: left", "text-align: right"%}')
253
+ end
254
+
255
+ def test_multiple_cycles
256
+ assert_template_result('1 2 1 1 2 3 1',
257
+ '{%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%}')
258
+ end
259
+
260
+ def test_multiple_named_cycles
261
+ assert_template_result('one one two two one one',
262
+ '{%cycle 1: "one", "two" %} {%cycle 2: "one", "two" %} {%cycle 1: "one", "two" %} {%cycle 2: "one", "two" %} {%cycle 1: "one", "two" %} {%cycle 2: "one", "two" %}')
263
+ end
264
+
265
+ def test_multiple_named_cycles_with_names_from_context
266
+ assigns = {"var1" => 1, "var2" => 2 }
267
+ assert_template_result('one one two two one one',
268
+ '{%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)
269
+ end
270
+
271
+ def test_size_of_array
272
+ assigns = {"array" => [1,2,3,4]}
273
+ assert_template_result('array has 4 elements', "array has {{ array.size }} elements", assigns)
274
+ end
275
+
276
+ def test_size_of_hash
277
+ assigns = {"hash" => {:a => 1, :b => 2, :c=> 3, :d => 4}}
278
+ assert_template_result('hash has 4 elements', "hash has {{ hash.size }} elements", assigns)
279
+ end
280
+
281
+ def test_illegal_symbols
282
+ assert_template_result('', '{% if true == empty %}?{% endif %}', {})
283
+ assert_template_result('', '{% if true == null %}?{% endif %}', {})
284
+ assert_template_result('', '{% if empty == true %}?{% endif %}', {})
285
+ assert_template_result('', '{% if null == true %}?{% endif %}', {})
286
+ end
287
+
288
+ def test_ifchanged
289
+ assigns = {'array' => [ 1, 1, 2, 2, 3, 3] }
290
+ assert_template_result('123','{%for item in array%}{%ifchanged%}{{item}}{% endifchanged %}{%endfor%}',assigns)
291
+
292
+ assigns = {'array' => [ 1, 1, 1, 1] }
293
+ assert_template_result('1','{%for item in array%}{%ifchanged%}{{item}}{% endifchanged %}{%endfor%}',assigns)
294
+ end
295
+ end # StandardTagTest