liquid 3.0.6 → 4.0.3

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 (103) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +154 -58
  3. data/{MIT-LICENSE → LICENSE} +0 -0
  4. data/README.md +33 -0
  5. data/lib/liquid/block.rb +42 -125
  6. data/lib/liquid/block_body.rb +99 -79
  7. data/lib/liquid/condition.rb +52 -32
  8. data/lib/liquid/context.rb +57 -51
  9. data/lib/liquid/document.rb +19 -9
  10. data/lib/liquid/drop.rb +17 -16
  11. data/lib/liquid/errors.rb +20 -24
  12. data/lib/liquid/expression.rb +26 -10
  13. data/lib/liquid/extensions.rb +19 -7
  14. data/lib/liquid/file_system.rb +11 -11
  15. data/lib/liquid/forloop_drop.rb +42 -0
  16. data/lib/liquid/i18n.rb +6 -6
  17. data/lib/liquid/interrupts.rb +1 -2
  18. data/lib/liquid/lexer.rb +12 -8
  19. data/lib/liquid/locales/en.yml +6 -2
  20. data/lib/liquid/parse_context.rb +38 -0
  21. data/lib/liquid/parse_tree_visitor.rb +42 -0
  22. data/lib/liquid/parser_switching.rb +4 -4
  23. data/lib/liquid/profiler/hooks.rb +7 -7
  24. data/lib/liquid/profiler.rb +18 -19
  25. data/lib/liquid/range_lookup.rb +16 -1
  26. data/lib/liquid/resource_limits.rb +23 -0
  27. data/lib/liquid/standardfilters.rb +207 -61
  28. data/lib/liquid/strainer.rb +15 -8
  29. data/lib/liquid/tablerowloop_drop.rb +62 -0
  30. data/lib/liquid/tag.rb +9 -8
  31. data/lib/liquid/tags/assign.rb +25 -4
  32. data/lib/liquid/tags/break.rb +0 -3
  33. data/lib/liquid/tags/capture.rb +1 -1
  34. data/lib/liquid/tags/case.rb +27 -12
  35. data/lib/liquid/tags/comment.rb +2 -2
  36. data/lib/liquid/tags/cycle.rb +16 -8
  37. data/lib/liquid/tags/decrement.rb +1 -4
  38. data/lib/liquid/tags/for.rb +103 -75
  39. data/lib/liquid/tags/if.rb +60 -44
  40. data/lib/liquid/tags/ifchanged.rb +0 -2
  41. data/lib/liquid/tags/include.rb +71 -51
  42. data/lib/liquid/tags/raw.rb +32 -4
  43. data/lib/liquid/tags/table_row.rb +21 -31
  44. data/lib/liquid/tags/unless.rb +3 -4
  45. data/lib/liquid/template.rb +42 -54
  46. data/lib/liquid/tokenizer.rb +31 -0
  47. data/lib/liquid/truffle.rb +5 -0
  48. data/lib/liquid/utils.rb +52 -8
  49. data/lib/liquid/variable.rb +59 -46
  50. data/lib/liquid/variable_lookup.rb +14 -6
  51. data/lib/liquid/version.rb +2 -1
  52. data/lib/liquid.rb +10 -7
  53. data/test/integration/assign_test.rb +8 -8
  54. data/test/integration/blank_test.rb +14 -14
  55. data/test/integration/block_test.rb +12 -0
  56. data/test/integration/context_test.rb +2 -2
  57. data/test/integration/document_test.rb +19 -0
  58. data/test/integration/drop_test.rb +42 -40
  59. data/test/integration/error_handling_test.rb +96 -43
  60. data/test/integration/filter_test.rb +60 -20
  61. data/test/integration/hash_ordering_test.rb +9 -9
  62. data/test/integration/output_test.rb +26 -27
  63. data/test/integration/parse_tree_visitor_test.rb +247 -0
  64. data/test/integration/parsing_quirks_test.rb +19 -13
  65. data/test/integration/render_profiling_test.rb +20 -20
  66. data/test/integration/security_test.rb +23 -7
  67. data/test/integration/standard_filter_test.rb +426 -46
  68. data/test/integration/tags/break_tag_test.rb +1 -2
  69. data/test/integration/tags/continue_tag_test.rb +0 -1
  70. data/test/integration/tags/for_tag_test.rb +135 -100
  71. data/test/integration/tags/if_else_tag_test.rb +75 -77
  72. data/test/integration/tags/include_tag_test.rb +50 -31
  73. data/test/integration/tags/increment_tag_test.rb +10 -11
  74. data/test/integration/tags/raw_tag_test.rb +7 -1
  75. data/test/integration/tags/standard_tag_test.rb +121 -122
  76. data/test/integration/tags/statements_test.rb +3 -5
  77. data/test/integration/tags/table_row_test.rb +20 -19
  78. data/test/integration/tags/unless_else_tag_test.rb +6 -6
  79. data/test/integration/template_test.rb +199 -49
  80. data/test/integration/trim_mode_test.rb +529 -0
  81. data/test/integration/variable_test.rb +27 -13
  82. data/test/test_helper.rb +33 -6
  83. data/test/truffle/truffle_test.rb +9 -0
  84. data/test/unit/block_unit_test.rb +8 -5
  85. data/test/unit/condition_unit_test.rb +94 -77
  86. data/test/unit/context_unit_test.rb +69 -72
  87. data/test/unit/file_system_unit_test.rb +3 -3
  88. data/test/unit/i18n_unit_test.rb +2 -2
  89. data/test/unit/lexer_unit_test.rb +12 -9
  90. data/test/unit/parser_unit_test.rb +2 -2
  91. data/test/unit/regexp_unit_test.rb +1 -1
  92. data/test/unit/strainer_unit_test.rb +96 -1
  93. data/test/unit/tag_unit_test.rb +7 -2
  94. data/test/unit/tags/case_tag_unit_test.rb +1 -1
  95. data/test/unit/tags/for_tag_unit_test.rb +2 -2
  96. data/test/unit/tags/if_tag_unit_test.rb +1 -1
  97. data/test/unit/template_unit_test.rb +14 -5
  98. data/test/unit/tokenizer_unit_test.rb +24 -7
  99. data/test/unit/variable_unit_test.rb +60 -43
  100. metadata +62 -50
  101. data/lib/liquid/module_ex.rb +0 -62
  102. data/lib/liquid/token.rb +0 -18
  103. data/test/unit/module_ex_unit_test.rb +0 -87
@@ -4,101 +4,100 @@ class IfElseTagTest < Minitest::Test
4
4
  include Liquid
5
5
 
6
6
  def test_if
7
- assert_template_result(' ',' {% if false %} this text should not go into the output {% endif %} ')
7
+ assert_template_result(' ', ' {% if false %} this text should not go into the output {% endif %} ')
8
8
  assert_template_result(' this text should go into the output ',
9
- ' {% if true %} this text should go into the output {% endif %} ')
10
- assert_template_result(' you rock ?','{% if false %} you suck {% endif %} {% if true %} you rock {% endif %}?')
9
+ ' {% if true %} this text should go into the output {% endif %} ')
10
+ assert_template_result(' you rock ?', '{% if false %} you suck {% endif %} {% if true %} you rock {% endif %}?')
11
11
  end
12
12
 
13
13
  def test_literal_comparisons
14
- assert_template_result(' NO ','{% assign v = false %}{% if v %} YES {% else %} NO {% endif %}')
15
- assert_template_result(' YES ','{% assign v = nil %}{% if v == nil %} YES {% else %} NO {% endif %}')
14
+ assert_template_result(' NO ', '{% assign v = false %}{% if v %} YES {% else %} NO {% endif %}')
15
+ assert_template_result(' YES ', '{% assign v = nil %}{% if v == nil %} YES {% else %} NO {% endif %}')
16
16
  end
17
17
 
18
18
  def test_if_else
19
- assert_template_result(' YES ','{% if false %} NO {% else %} YES {% endif %}')
20
- assert_template_result(' YES ','{% if true %} YES {% else %} NO {% endif %}')
21
- assert_template_result(' YES ','{% if "foo" %} YES {% else %} NO {% endif %}')
19
+ assert_template_result(' YES ', '{% if false %} NO {% else %} YES {% endif %}')
20
+ assert_template_result(' YES ', '{% if true %} YES {% else %} NO {% endif %}')
21
+ assert_template_result(' YES ', '{% if "foo" %} YES {% else %} NO {% endif %}')
22
22
  end
23
23
 
24
24
  def test_if_boolean
25
- assert_template_result(' YES ','{% if var %} YES {% endif %}', 'var' => true)
25
+ assert_template_result(' YES ', '{% if var %} YES {% endif %}', 'var' => true)
26
26
  end
27
27
 
28
28
  def test_if_or
29
- assert_template_result(' YES ','{% if a or b %} YES {% endif %}', 'a' => true, 'b' => true)
30
- assert_template_result(' YES ','{% if a or b %} YES {% endif %}', 'a' => true, 'b' => false)
31
- assert_template_result(' YES ','{% if a or b %} YES {% endif %}', 'a' => false, 'b' => true)
32
- assert_template_result('', '{% if a or b %} YES {% endif %}', 'a' => false, 'b' => false)
29
+ assert_template_result(' YES ', '{% if a or b %} YES {% endif %}', 'a' => true, 'b' => true)
30
+ assert_template_result(' YES ', '{% if a or b %} YES {% endif %}', 'a' => true, 'b' => false)
31
+ assert_template_result(' YES ', '{% if a or b %} YES {% endif %}', 'a' => false, 'b' => true)
32
+ assert_template_result('', '{% if a or b %} YES {% endif %}', 'a' => false, 'b' => false)
33
33
 
34
- assert_template_result(' YES ','{% if a or b or c %} YES {% endif %}', 'a' => false, 'b' => false, 'c' => true)
35
- assert_template_result('', '{% if a or b or c %} YES {% endif %}', 'a' => false, 'b' => false, 'c' => false)
34
+ assert_template_result(' YES ', '{% if a or b or c %} YES {% endif %}', 'a' => false, 'b' => false, 'c' => true)
35
+ assert_template_result('', '{% if a or b or c %} YES {% endif %}', 'a' => false, 'b' => false, 'c' => false)
36
36
  end
37
37
 
38
38
  def test_if_or_with_operators
39
- assert_template_result(' YES ','{% if a == true or b == true %} YES {% endif %}', 'a' => true, 'b' => true)
40
- assert_template_result(' YES ','{% if a == true or b == false %} YES {% endif %}', 'a' => true, 'b' => true)
41
- assert_template_result('','{% if a == false or b == false %} YES {% endif %}', 'a' => true, 'b' => true)
39
+ assert_template_result(' YES ', '{% if a == true or b == true %} YES {% endif %}', 'a' => true, 'b' => true)
40
+ assert_template_result(' YES ', '{% if a == true or b == false %} YES {% endif %}', 'a' => true, 'b' => true)
41
+ assert_template_result('', '{% if a == false or b == false %} YES {% endif %}', 'a' => true, 'b' => true)
42
42
  end
43
43
 
44
44
  def test_comparison_of_strings_containing_and_or_or
45
45
  awful_markup = "a == 'and' and b == 'or' and c == 'foo and bar' and d == 'bar or baz' and e == 'foo' and foo and bar"
46
- assigns = {'a' => 'and', 'b' => 'or', 'c' => 'foo and bar', 'd' => 'bar or baz', 'e' => 'foo', 'foo' => true, 'bar' => true}
47
- assert_template_result(' YES ',"{% if #{awful_markup} %} YES {% endif %}", assigns)
46
+ assigns = { 'a' => 'and', 'b' => 'or', 'c' => 'foo and bar', 'd' => 'bar or baz', 'e' => 'foo', 'foo' => true, 'bar' => true }
47
+ assert_template_result(' YES ', "{% if #{awful_markup} %} YES {% endif %}", assigns)
48
48
  end
49
49
 
50
50
  def test_comparison_of_expressions_starting_with_and_or_or
51
- assigns = {'order' => {'items_count' => 0}, 'android' => {'name' => 'Roy'}}
52
- assert_template_result( "YES",
53
- "{% if android.name == 'Roy' %}YES{% endif %}",
54
- assigns)
55
- assert_template_result( "YES",
56
- "{% if order.items_count == 0 %}YES{% endif %}",
57
- assigns)
51
+ assigns = { 'order' => { 'items_count' => 0 }, 'android' => { 'name' => 'Roy' } }
52
+ assert_template_result("YES",
53
+ "{% if android.name == 'Roy' %}YES{% endif %}",
54
+ assigns)
55
+ assert_template_result("YES",
56
+ "{% if order.items_count == 0 %}YES{% endif %}",
57
+ assigns)
58
58
  end
59
59
 
60
60
  def test_if_and
61
- assert_template_result(' YES ','{% if true and true %} YES {% endif %}')
62
- assert_template_result('','{% if false and true %} YES {% endif %}')
63
- assert_template_result('','{% if false and true %} YES {% endif %}')
61
+ assert_template_result(' YES ', '{% if true and true %} YES {% endif %}')
62
+ assert_template_result('', '{% if false and true %} YES {% endif %}')
63
+ assert_template_result('', '{% if false and true %} YES {% endif %}')
64
64
  end
65
65
 
66
-
67
66
  def test_hash_miss_generates_false
68
- assert_template_result('','{% if foo.bar %} NO {% endif %}', 'foo' => {})
67
+ assert_template_result('', '{% if foo.bar %} NO {% endif %}', 'foo' => {})
69
68
  end
70
69
 
71
70
  def test_if_from_variable
72
- assert_template_result('','{% if var %} NO {% endif %}', 'var' => false)
73
- assert_template_result('','{% if var %} NO {% endif %}', 'var' => nil)
74
- assert_template_result('','{% if foo.bar %} NO {% endif %}', 'foo' => {'bar' => false})
75
- assert_template_result('','{% if foo.bar %} NO {% endif %}', 'foo' => {})
76
- assert_template_result('','{% if foo.bar %} NO {% endif %}', 'foo' => nil)
77
- assert_template_result('','{% if foo.bar %} NO {% endif %}', 'foo' => true)
78
-
79
- assert_template_result(' YES ','{% if var %} YES {% endif %}', 'var' => "text")
80
- assert_template_result(' YES ','{% if var %} YES {% endif %}', 'var' => true)
81
- assert_template_result(' YES ','{% if var %} YES {% endif %}', 'var' => 1)
82
- assert_template_result(' YES ','{% if var %} YES {% endif %}', 'var' => {})
83
- assert_template_result(' YES ','{% if var %} YES {% endif %}', 'var' => [])
84
- assert_template_result(' YES ','{% if "foo" %} YES {% endif %}')
85
- assert_template_result(' YES ','{% if foo.bar %} YES {% endif %}', 'foo' => {'bar' => true})
86
- assert_template_result(' YES ','{% if foo.bar %} YES {% endif %}', 'foo' => {'bar' => "text"})
87
- assert_template_result(' YES ','{% if foo.bar %} YES {% endif %}', 'foo' => {'bar' => 1 })
88
- assert_template_result(' YES ','{% if foo.bar %} YES {% endif %}', 'foo' => {'bar' => {} })
89
- assert_template_result(' YES ','{% if foo.bar %} YES {% endif %}', 'foo' => {'bar' => [] })
90
-
91
- assert_template_result(' YES ','{% if var %} NO {% else %} YES {% endif %}', 'var' => false)
92
- assert_template_result(' YES ','{% if var %} NO {% else %} YES {% endif %}', 'var' => nil)
93
- assert_template_result(' YES ','{% if var %} YES {% else %} NO {% endif %}', 'var' => true)
94
- assert_template_result(' YES ','{% if "foo" %} YES {% else %} NO {% endif %}', 'var' => "text")
95
-
96
- assert_template_result(' YES ','{% if foo.bar %} NO {% else %} YES {% endif %}', 'foo' => {'bar' => false})
97
- assert_template_result(' YES ','{% if foo.bar %} YES {% else %} NO {% endif %}', 'foo' => {'bar' => true})
98
- assert_template_result(' YES ','{% if foo.bar %} YES {% else %} NO {% endif %}', 'foo' => {'bar' => "text"})
99
- assert_template_result(' YES ','{% if foo.bar %} NO {% else %} YES {% endif %}', 'foo' => {'notbar' => true})
100
- assert_template_result(' YES ','{% if foo.bar %} NO {% else %} YES {% endif %}', 'foo' => {})
101
- assert_template_result(' YES ','{% if foo.bar %} NO {% else %} YES {% endif %}', 'notfoo' => {'bar' => true})
71
+ assert_template_result('', '{% if var %} NO {% endif %}', 'var' => false)
72
+ assert_template_result('', '{% if var %} NO {% endif %}', 'var' => nil)
73
+ assert_template_result('', '{% if foo.bar %} NO {% endif %}', 'foo' => { 'bar' => false })
74
+ assert_template_result('', '{% if foo.bar %} NO {% endif %}', 'foo' => {})
75
+ assert_template_result('', '{% if foo.bar %} NO {% endif %}', 'foo' => nil)
76
+ assert_template_result('', '{% if foo.bar %} NO {% endif %}', 'foo' => true)
77
+
78
+ assert_template_result(' YES ', '{% if var %} YES {% endif %}', 'var' => "text")
79
+ assert_template_result(' YES ', '{% if var %} YES {% endif %}', 'var' => true)
80
+ assert_template_result(' YES ', '{% if var %} YES {% endif %}', 'var' => 1)
81
+ assert_template_result(' YES ', '{% if var %} YES {% endif %}', 'var' => {})
82
+ assert_template_result(' YES ', '{% if var %} YES {% endif %}', 'var' => [])
83
+ assert_template_result(' YES ', '{% if "foo" %} YES {% endif %}')
84
+ assert_template_result(' YES ', '{% if foo.bar %} YES {% endif %}', 'foo' => { 'bar' => true })
85
+ assert_template_result(' YES ', '{% if foo.bar %} YES {% endif %}', 'foo' => { 'bar' => "text" })
86
+ assert_template_result(' YES ', '{% if foo.bar %} YES {% endif %}', 'foo' => { 'bar' => 1 })
87
+ assert_template_result(' YES ', '{% if foo.bar %} YES {% endif %}', 'foo' => { 'bar' => {} })
88
+ assert_template_result(' YES ', '{% if foo.bar %} YES {% endif %}', 'foo' => { 'bar' => [] })
89
+
90
+ assert_template_result(' YES ', '{% if var %} NO {% else %} YES {% endif %}', 'var' => false)
91
+ assert_template_result(' YES ', '{% if var %} NO {% else %} YES {% endif %}', 'var' => nil)
92
+ assert_template_result(' YES ', '{% if var %} YES {% else %} NO {% endif %}', 'var' => true)
93
+ assert_template_result(' YES ', '{% if "foo" %} YES {% else %} NO {% endif %}', 'var' => "text")
94
+
95
+ assert_template_result(' YES ', '{% if foo.bar %} NO {% else %} YES {% endif %}', 'foo' => { 'bar' => false })
96
+ assert_template_result(' YES ', '{% if foo.bar %} YES {% else %} NO {% endif %}', 'foo' => { 'bar' => true })
97
+ assert_template_result(' YES ', '{% if foo.bar %} YES {% else %} NO {% endif %}', 'foo' => { 'bar' => "text" })
98
+ assert_template_result(' YES ', '{% if foo.bar %} NO {% else %} YES {% endif %}', 'foo' => { 'notbar' => true })
99
+ assert_template_result(' YES ', '{% if foo.bar %} NO {% else %} YES {% endif %}', 'foo' => {})
100
+ assert_template_result(' YES ', '{% if foo.bar %} NO {% else %} YES {% endif %}', 'notfoo' => { 'bar' => true })
102
101
  end
103
102
 
104
103
  def test_nested_if
@@ -110,31 +109,30 @@ class IfElseTagTest < Minitest::Test
110
109
  assert_template_result(' YES ', '{% if true %}{% if true %} YES {% else %} NO {% endif %}{% else %} NO {% endif %}')
111
110
  assert_template_result(' YES ', '{% if true %}{% if false %} NO {% else %} YES {% endif %}{% else %} NO {% endif %}')
112
111
  assert_template_result(' YES ', '{% if false %}{% if true %} NO {% else %} NONO {% endif %}{% else %} YES {% endif %}')
113
-
114
112
  end
115
113
 
116
114
  def test_comparisons_on_null
117
- assert_template_result('','{% if null < 10 %} NO {% endif %}')
118
- assert_template_result('','{% if null <= 10 %} NO {% endif %}')
119
- assert_template_result('','{% if null >= 10 %} NO {% endif %}')
120
- assert_template_result('','{% if null > 10 %} NO {% endif %}')
115
+ assert_template_result('', '{% if null < 10 %} NO {% endif %}')
116
+ assert_template_result('', '{% if null <= 10 %} NO {% endif %}')
117
+ assert_template_result('', '{% if null >= 10 %} NO {% endif %}')
118
+ assert_template_result('', '{% if null > 10 %} NO {% endif %}')
121
119
 
122
- assert_template_result('','{% if 10 < null %} NO {% endif %}')
123
- assert_template_result('','{% if 10 <= null %} NO {% endif %}')
124
- assert_template_result('','{% if 10 >= null %} NO {% endif %}')
125
- assert_template_result('','{% if 10 > null %} NO {% endif %}')
120
+ assert_template_result('', '{% if 10 < null %} NO {% endif %}')
121
+ assert_template_result('', '{% if 10 <= null %} NO {% endif %}')
122
+ assert_template_result('', '{% if 10 >= null %} NO {% endif %}')
123
+ assert_template_result('', '{% if 10 > null %} NO {% endif %}')
126
124
  end
127
125
 
128
126
  def test_else_if
129
- assert_template_result('0','{% if 0 == 0 %}0{% elsif 1 == 1%}1{% else %}2{% endif %}')
130
- assert_template_result('1','{% if 0 != 0 %}0{% elsif 1 == 1%}1{% else %}2{% endif %}')
131
- assert_template_result('2','{% if 0 != 0 %}0{% elsif 1 != 1%}1{% else %}2{% endif %}')
127
+ assert_template_result('0', '{% if 0 == 0 %}0{% elsif 1 == 1%}1{% else %}2{% endif %}')
128
+ assert_template_result('1', '{% if 0 != 0 %}0{% elsif 1 == 1%}1{% else %}2{% endif %}')
129
+ assert_template_result('2', '{% if 0 != 0 %}0{% elsif 1 != 1%}1{% else %}2{% endif %}')
132
130
 
133
- assert_template_result('elsif','{% if false %}if{% elsif true %}elsif{% endif %}')
131
+ assert_template_result('elsif', '{% if false %}if{% elsif true %}elsif{% endif %}')
134
132
  end
135
133
 
136
134
  def test_syntax_error_no_variable
137
- assert_raises(SyntaxError){ assert_template_result('', '{% if jerry == 1 %}')}
135
+ assert_raises(SyntaxError){ assert_template_result('', '{% if jerry == 1 %}') }
138
136
  end
139
137
 
140
138
  def test_syntax_error_no_expression
@@ -156,7 +154,7 @@ class IfElseTagTest < Minitest::Test
156
154
  Condition.operators['contains'] = :[]
157
155
 
158
156
  assert_template_result('yes',
159
- %({% if 'gnomeslab-and-or-liquid' contains 'gnomeslab-and-or-liquid' %}yes{% endif %}))
157
+ %({% if 'gnomeslab-and-or-liquid' contains 'gnomeslab-and-or-liquid' %}yes{% endif %}))
160
158
  ensure
161
159
  Condition.operators['contains'] = original_op
162
160
  end
@@ -1,7 +1,7 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class TestFileSystem
4
- def read_template_file(template_path, context)
4
+ def read_template_file(template_path)
5
5
  case template_path
6
6
  when "product"
7
7
  "Product: {{ product.title }} "
@@ -30,6 +30,9 @@ class TestFileSystem
30
30
  when 'assignments'
31
31
  "{% assign foo = 'bar' %}"
32
32
 
33
+ when 'break'
34
+ "{% break %}"
35
+
33
36
  else
34
37
  template_path
35
38
  end
@@ -37,14 +40,14 @@ class TestFileSystem
37
40
  end
38
41
 
39
42
  class OtherFileSystem
40
- def read_template_file(template_path, context)
43
+ def read_template_file(template_path)
41
44
  'from OtherFileSystem'
42
45
  end
43
46
  end
44
47
 
45
48
  class CountingFileSystem
46
49
  attr_reader :count
47
- def read_template_file(template_path, context)
50
+ def read_template_file(template_path)
48
51
  @count ||= 0
49
52
  @count += 1
50
53
  'from CountingFileSystem'
@@ -77,23 +80,22 @@ class IncludeTagTest < Minitest::Test
77
80
 
78
81
  def test_include_tag_looks_for_file_system_in_registers_first
79
82
  assert_equal 'from OtherFileSystem',
80
- Template.parse("{% include 'pick_a_source' %}").render!({}, :registers => {:file_system => OtherFileSystem.new})
83
+ Template.parse("{% include 'pick_a_source' %}").render!({}, registers: { file_system: OtherFileSystem.new })
81
84
  end
82
85
 
83
-
84
86
  def test_include_tag_with
85
87
  assert_template_result "Product: Draft 151cm ",
86
- "{% include 'product' with products[0] %}", "products" => [ {'title' => 'Draft 151cm'}, {'title' => 'Element 155cm'} ]
88
+ "{% include 'product' with products[0] %}", "products" => [ { 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' } ]
87
89
  end
88
90
 
89
91
  def test_include_tag_with_default_name
90
92
  assert_template_result "Product: Draft 151cm ",
91
- "{% include 'product' %}", "product" => {'title' => 'Draft 151cm'}
93
+ "{% include 'product' %}", "product" => { 'title' => 'Draft 151cm' }
92
94
  end
93
95
 
94
96
  def test_include_tag_for
95
97
  assert_template_result "Product: Draft 151cm Product: Element 155cm ",
96
- "{% include 'product' for products %}", "products" => [ {'title' => 'Draft 151cm'}, {'title' => 'Element 155cm'} ]
98
+ "{% include 'product' for products %}", "products" => [ { 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' } ]
97
99
  end
98
100
 
99
101
  def test_include_tag_with_local_variables
@@ -108,7 +110,7 @@ class IncludeTagTest < Minitest::Test
108
110
  def test_include_tag_with_multiple_local_variables_from_context
109
111
  assert_template_result "Locale: test123 test321",
110
112
  "{% include 'locale_variables' echo1: echo1, echo2: more_echos.echo2 %}",
111
- 'echo1' => 'test123', 'more_echos' => { "echo2" => 'test321'}
113
+ 'echo1' => 'test123', 'more_echos' => { "echo2" => 'test321' }
112
114
  end
113
115
 
114
116
  def test_included_templates_assigns_variables
@@ -123,38 +125,24 @@ class IncludeTagTest < Minitest::Test
123
125
 
124
126
  def test_nested_include_with_variable
125
127
  assert_template_result "Product: Draft 151cm details ",
126
- "{% include 'nested_product_template' with product %}", "product" => {"title" => 'Draft 151cm'}
128
+ "{% include 'nested_product_template' with product %}", "product" => { "title" => 'Draft 151cm' }
127
129
 
128
130
  assert_template_result "Product: Draft 151cm details Product: Element 155cm details ",
129
- "{% include 'nested_product_template' for products %}", "products" => [{"title" => 'Draft 151cm'}, {"title" => 'Element 155cm'}]
131
+ "{% include 'nested_product_template' for products %}", "products" => [{ "title" => 'Draft 151cm' }, { "title" => 'Element 155cm' }]
130
132
  end
131
133
 
132
134
  def test_recursively_included_template_does_not_produce_endless_loop
133
-
134
135
  infinite_file_system = Class.new do
135
- def read_template_file(template_path, context)
136
+ def read_template_file(template_path)
136
137
  "-{% include 'loop' %}"
137
138
  end
138
139
  end
139
140
 
140
141
  Liquid::Template.file_system = infinite_file_system.new
141
142
 
142
- assert_raises(Liquid::StackLevelError, SystemStackError) do
143
+ assert_raises(Liquid::StackLevelError) do
143
144
  Template.parse("{% include 'loop' %}").render!
144
145
  end
145
-
146
- end
147
-
148
- def test_backwards_compatability_support_for_overridden_read_template_file
149
- infinite_file_system = Class.new do
150
- def read_template_file(template_path) # testing only one argument here.
151
- "- hi mom"
152
- end
153
- end
154
-
155
- Liquid::Template.file_system = infinite_file_system.new
156
-
157
- Template.parse("{% include 'hi_mom' %}").render!
158
146
  end
159
147
 
160
148
  def test_dynamically_choosen_template
@@ -162,24 +150,24 @@ class IncludeTagTest < Minitest::Test
162
150
  assert_template_result "Test321", "{% include template %}", "template" => 'Test321'
163
151
 
164
152
  assert_template_result "Product: Draft 151cm ", "{% include template for product %}",
165
- "template" => 'product', 'product' => { 'title' => 'Draft 151cm'}
153
+ "template" => 'product', 'product' => { 'title' => 'Draft 151cm' }
166
154
  end
167
155
 
168
156
  def test_include_tag_caches_second_read_of_same_partial
169
157
  file_system = CountingFileSystem.new
170
158
  assert_equal 'from CountingFileSystemfrom CountingFileSystem',
171
- Template.parse("{% include 'pick_a_source' %}{% include 'pick_a_source' %}").render!({}, :registers => {:file_system => file_system})
159
+ Template.parse("{% include 'pick_a_source' %}{% include 'pick_a_source' %}").render!({}, registers: { file_system: file_system })
172
160
  assert_equal 1, file_system.count
173
161
  end
174
162
 
175
163
  def test_include_tag_doesnt_cache_partials_across_renders
176
164
  file_system = CountingFileSystem.new
177
165
  assert_equal 'from CountingFileSystem',
178
- Template.parse("{% include 'pick_a_source' %}").render!({}, :registers => {:file_system => file_system})
166
+ Template.parse("{% include 'pick_a_source' %}").render!({}, registers: { file_system: file_system })
179
167
  assert_equal 1, file_system.count
180
168
 
181
169
  assert_equal 'from CountingFileSystem',
182
- Template.parse("{% include 'pick_a_source' %}").render!({}, :registers => {:file_system => file_system})
170
+ Template.parse("{% include 'pick_a_source' %}").render!({}, registers: { file_system: file_system })
183
171
  assert_equal 2, file_system.count
184
172
  end
185
173
 
@@ -231,4 +219,35 @@ class IncludeTagTest < Minitest::Test
231
219
  assert_equal 'x', Template.parse("{% include template %}", error_mode: :strict, include_options_blacklist: [:error_mode]).render!("template" => '{{ "X" || downcase }}')
232
220
  end
233
221
  end
222
+
223
+ def test_render_raise_argument_error_when_template_is_undefined
224
+ assert_raises(Liquid::ArgumentError) do
225
+ template = Liquid::Template.parse('{% include undefined_variable %}')
226
+ template.render!
227
+ end
228
+ assert_raises(Liquid::ArgumentError) do
229
+ template = Liquid::Template.parse('{% include nil %}')
230
+ template.render!
231
+ end
232
+ end
233
+
234
+ def test_including_via_variable_value
235
+ assert_template_result "from TestFileSystem", "{% assign page = 'pick_a_source' %}{% include page %}"
236
+
237
+ assert_template_result "Product: Draft 151cm ", "{% assign page = 'product' %}{% include page %}", "product" => { 'title' => 'Draft 151cm' }
238
+
239
+ assert_template_result "Product: Draft 151cm ", "{% assign page = 'product' %}{% include page for foo %}", "foo" => { 'title' => 'Draft 151cm' }
240
+ end
241
+
242
+ def test_including_with_strict_variables
243
+ template = Liquid::Template.parse("{% include 'simple' %}", error_mode: :warn)
244
+ template.render(nil, strict_variables: true)
245
+
246
+ assert_equal [], template.errors
247
+ end
248
+
249
+ def test_break_through_include
250
+ assert_template_result "1", "{% for i in (1..3) %}{{ i }}{% break %}{{ i }}{% endfor %}"
251
+ assert_template_result "1", "{% for i in (1..3) %}{{ i }}{% include 'break' %}{{ i }}{% endfor %}"
252
+ end
234
253
  end # IncludeTagTest
@@ -4,21 +4,20 @@ class IncrementTagTest < Minitest::Test
4
4
  include Liquid
5
5
 
6
6
  def test_inc
7
- assert_template_result('0','{%increment port %}', {})
8
- assert_template_result('0 1','{%increment port %} {%increment port%}', {})
7
+ assert_template_result('0', '{%increment port %}', {})
8
+ assert_template_result('0 1', '{%increment port %} {%increment port%}', {})
9
9
  assert_template_result('0 0 1 2 1',
10
- '{%increment port %} {%increment starboard%} ' +
11
- '{%increment port %} {%increment port%} ' +
12
- '{%increment starboard %}', {})
10
+ '{%increment port %} {%increment starboard%} ' \
11
+ '{%increment port %} {%increment port%} ' \
12
+ '{%increment starboard %}', {})
13
13
  end
14
14
 
15
15
  def test_dec
16
- assert_template_result('9','{%decrement port %}', { 'port' => 10})
17
- assert_template_result('-1 -2','{%decrement port %} {%decrement port%}', {})
16
+ assert_template_result('9', '{%decrement port %}', { 'port' => 10 })
17
+ assert_template_result('-1 -2', '{%decrement port %} {%decrement port%}', {})
18
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 })
19
+ '{%increment port %} {%increment starboard%} ' \
20
+ '{%increment port %} {%decrement port%} ' \
21
+ '{%decrement starboard %}', { 'port' => 1, 'starboard' => 5 })
22
22
  end
23
-
24
23
  end
@@ -5,7 +5,7 @@ class RawTagTest < Minitest::Test
5
5
 
6
6
  def test_tag_in_raw
7
7
  assert_template_result '{% comment %} test {% endcomment %}',
8
- '{% raw %}{% comment %} test {% endcomment %}{% endraw %}'
8
+ '{% raw %}{% comment %} test {% endcomment %}{% endraw %}'
9
9
  end
10
10
 
11
11
  def test_output_in_raw
@@ -22,4 +22,10 @@ class RawTagTest < Minitest::Test
22
22
  assert_template_result ' test {% raw %} {% endraw %}', '{% raw %} test {% raw %} {% {% endraw %}endraw %}'
23
23
  assert_template_result ' Foobar {{ invalid 1', '{% raw %} Foobar {{ invalid {% endraw %}{{ 1 }}'
24
24
  end
25
+
26
+ def test_invalid_raw
27
+ assert_match_syntax_error(/tag was never closed/, '{% raw %} foo')
28
+ assert_match_syntax_error(/Valid syntax/, '{% raw } foo {% endraw %}')
29
+ assert_match_syntax_error(/Valid syntax/, '{% raw } foo %}{% endraw %}')
30
+ end
25
31
  end