liquid 4.0.3 → 5.0.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 (125) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +43 -0
  3. data/README.md +6 -0
  4. data/lib/liquid.rb +17 -5
  5. data/lib/liquid/block.rb +31 -14
  6. data/lib/liquid/block_body.rb +166 -54
  7. data/lib/liquid/condition.rb +39 -18
  8. data/lib/liquid/context.rb +106 -51
  9. data/lib/liquid/document.rb +47 -9
  10. data/lib/liquid/drop.rb +4 -2
  11. data/lib/liquid/errors.rb +20 -18
  12. data/lib/liquid/expression.rb +29 -34
  13. data/lib/liquid/extensions.rb +2 -0
  14. data/lib/liquid/file_system.rb +6 -4
  15. data/lib/liquid/forloop_drop.rb +11 -4
  16. data/lib/liquid/i18n.rb +5 -3
  17. data/lib/liquid/interrupts.rb +3 -1
  18. data/lib/liquid/lexer.rb +30 -23
  19. data/lib/liquid/locales/en.yml +3 -1
  20. data/lib/liquid/parse_context.rb +20 -4
  21. data/lib/liquid/parse_tree_visitor.rb +2 -2
  22. data/lib/liquid/parser.rb +30 -18
  23. data/lib/liquid/parser_switching.rb +17 -3
  24. data/lib/liquid/partial_cache.rb +24 -0
  25. data/lib/liquid/profiler.rb +67 -86
  26. data/lib/liquid/profiler/hooks.rb +26 -14
  27. data/lib/liquid/range_lookup.rb +5 -3
  28. data/lib/liquid/register.rb +6 -0
  29. data/lib/liquid/resource_limits.rb +47 -8
  30. data/lib/liquid/standardfilters.rb +67 -46
  31. data/lib/liquid/static_registers.rb +44 -0
  32. data/lib/liquid/strainer_factory.rb +36 -0
  33. data/lib/liquid/strainer_template.rb +53 -0
  34. data/lib/liquid/tablerowloop_drop.rb +6 -4
  35. data/lib/liquid/tag.rb +28 -6
  36. data/lib/liquid/tag/disableable.rb +22 -0
  37. data/lib/liquid/tag/disabler.rb +21 -0
  38. data/lib/liquid/tags/assign.rb +24 -10
  39. data/lib/liquid/tags/break.rb +8 -3
  40. data/lib/liquid/tags/capture.rb +11 -8
  41. data/lib/liquid/tags/case.rb +33 -27
  42. data/lib/liquid/tags/comment.rb +5 -3
  43. data/lib/liquid/tags/continue.rb +8 -3
  44. data/lib/liquid/tags/cycle.rb +25 -14
  45. data/lib/liquid/tags/decrement.rb +6 -3
  46. data/lib/liquid/tags/echo.rb +34 -0
  47. data/lib/liquid/tags/for.rb +68 -44
  48. data/lib/liquid/tags/if.rb +35 -23
  49. data/lib/liquid/tags/ifchanged.rb +11 -10
  50. data/lib/liquid/tags/include.rb +34 -47
  51. data/lib/liquid/tags/increment.rb +7 -3
  52. data/lib/liquid/tags/raw.rb +14 -11
  53. data/lib/liquid/tags/render.rb +84 -0
  54. data/lib/liquid/tags/table_row.rb +23 -19
  55. data/lib/liquid/tags/unless.rb +15 -15
  56. data/lib/liquid/template.rb +53 -72
  57. data/lib/liquid/template_factory.rb +9 -0
  58. data/lib/liquid/tokenizer.rb +17 -9
  59. data/lib/liquid/usage.rb +8 -0
  60. data/lib/liquid/utils.rb +5 -3
  61. data/lib/liquid/variable.rb +46 -41
  62. data/lib/liquid/variable_lookup.rb +8 -6
  63. data/lib/liquid/version.rb +2 -1
  64. data/test/integration/assign_test.rb +74 -5
  65. data/test/integration/blank_test.rb +11 -8
  66. data/test/integration/block_test.rb +47 -1
  67. data/test/integration/capture_test.rb +18 -10
  68. data/test/integration/context_test.rb +609 -5
  69. data/test/integration/document_test.rb +4 -2
  70. data/test/integration/drop_test.rb +67 -83
  71. data/test/integration/error_handling_test.rb +73 -61
  72. data/test/integration/expression_test.rb +46 -0
  73. data/test/integration/filter_test.rb +53 -42
  74. data/test/integration/hash_ordering_test.rb +5 -3
  75. data/test/integration/output_test.rb +26 -24
  76. data/test/integration/parsing_quirks_test.rb +19 -7
  77. data/test/integration/{render_profiling_test.rb → profiler_test.rb} +84 -25
  78. data/test/integration/security_test.rb +30 -21
  79. data/test/integration/standard_filter_test.rb +343 -281
  80. data/test/integration/tag/disableable_test.rb +59 -0
  81. data/test/integration/tag_test.rb +45 -0
  82. data/test/integration/tags/break_tag_test.rb +4 -2
  83. data/test/integration/tags/continue_tag_test.rb +4 -2
  84. data/test/integration/tags/echo_test.rb +13 -0
  85. data/test/integration/tags/for_tag_test.rb +107 -51
  86. data/test/integration/tags/if_else_tag_test.rb +5 -3
  87. data/test/integration/tags/include_tag_test.rb +70 -54
  88. data/test/integration/tags/increment_tag_test.rb +4 -2
  89. data/test/integration/tags/liquid_tag_test.rb +116 -0
  90. data/test/integration/tags/raw_tag_test.rb +14 -11
  91. data/test/integration/tags/render_tag_test.rb +213 -0
  92. data/test/integration/tags/standard_tag_test.rb +38 -31
  93. data/test/integration/tags/statements_test.rb +23 -21
  94. data/test/integration/tags/table_row_test.rb +2 -0
  95. data/test/integration/tags/unless_else_tag_test.rb +4 -2
  96. data/test/integration/template_test.rb +118 -124
  97. data/test/integration/trim_mode_test.rb +78 -44
  98. data/test/integration/variable_test.rb +43 -32
  99. data/test/test_helper.rb +75 -22
  100. data/test/unit/block_unit_test.rb +19 -24
  101. data/test/unit/condition_unit_test.rb +79 -77
  102. data/test/unit/file_system_unit_test.rb +6 -4
  103. data/test/unit/i18n_unit_test.rb +7 -5
  104. data/test/unit/lexer_unit_test.rb +11 -9
  105. data/test/{integration → unit}/parse_tree_visitor_test.rb +9 -2
  106. data/test/unit/parser_unit_test.rb +37 -35
  107. data/test/unit/partial_cache_unit_test.rb +128 -0
  108. data/test/unit/regexp_unit_test.rb +17 -15
  109. data/test/unit/static_registers_unit_test.rb +156 -0
  110. data/test/unit/strainer_factory_unit_test.rb +100 -0
  111. data/test/unit/strainer_template_unit_test.rb +82 -0
  112. data/test/unit/tag_unit_test.rb +5 -3
  113. data/test/unit/tags/case_tag_unit_test.rb +3 -1
  114. data/test/unit/tags/for_tag_unit_test.rb +4 -2
  115. data/test/unit/tags/if_tag_unit_test.rb +3 -1
  116. data/test/unit/template_factory_unit_test.rb +12 -0
  117. data/test/unit/template_unit_test.rb +19 -10
  118. data/test/unit/tokenizer_unit_test.rb +26 -19
  119. data/test/unit/variable_unit_test.rb +51 -49
  120. metadata +73 -47
  121. data/lib/liquid/strainer.rb +0 -66
  122. data/lib/liquid/truffle.rb +0 -5
  123. data/test/truffle/truffle_test.rb +0 -9
  124. data/test/unit/context_unit_test.rb +0 -489
  125. data/test/unit/strainer_unit_test.rb +0 -164
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
- class RenderProfilingTest < Minitest::Test
5
+ class ProfilerTest < Minitest::Test
4
6
  include Liquid
5
7
 
6
8
  class ProfilingFileSystem
@@ -17,35 +19,35 @@ class RenderProfilingTest < Minitest::Test
17
19
  t = Template.parse("{{ 'a string' | upcase }}")
18
20
  t.render!
19
21
 
20
- assert_nil t.profiler
22
+ assert_nil(t.profiler)
21
23
  end
22
24
 
23
25
  def test_parse_makes_available_simple_profiling
24
26
  t = Template.parse("{{ 'a string' | upcase }}", profile: true)
25
27
  t.render!
26
28
 
27
- assert_equal 1, t.profiler.length
29
+ assert_equal(1, t.profiler.length)
28
30
 
29
31
  node = t.profiler[0]
30
- assert_equal " 'a string' | upcase ", node.code
32
+ assert_equal(" 'a string' | upcase ", node.code)
31
33
  end
32
34
 
33
35
  def test_render_ignores_raw_strings_when_profiling
34
36
  t = Template.parse("This is raw string\nstuff\nNewline", profile: true)
35
37
  t.render!
36
38
 
37
- assert_equal 0, t.profiler.length
39
+ assert_equal(0, t.profiler.length)
38
40
  end
39
41
 
40
42
  def test_profiling_includes_line_numbers_of_liquid_nodes
41
43
  t = Template.parse("{{ 'a string' | upcase }}\n{% increment test %}", profile: true)
42
44
  t.render!
43
- assert_equal 2, t.profiler.length
45
+ assert_equal(2, t.profiler.length)
44
46
 
45
47
  # {{ 'a string' | upcase }}
46
- assert_equal 1, t.profiler[0].line_number
48
+ assert_equal(1, t.profiler[0].line_number)
47
49
  # {{ increment test }}
48
- assert_equal 2, t.profiler[1].line_number
50
+ assert_equal(2, t.profiler[1].line_number)
49
51
  end
50
52
 
51
53
  def test_profiling_includes_line_numbers_of_included_partials
@@ -55,9 +57,20 @@ class RenderProfilingTest < Minitest::Test
55
57
  included_children = t.profiler[0].children
56
58
 
57
59
  # {% assign template_name = 'a_template' %}
58
- assert_equal 1, included_children[0].line_number
60
+ assert_equal(1, included_children[0].line_number)
59
61
  # {{ template_name }}
60
- assert_equal 2, included_children[1].line_number
62
+ assert_equal(2, included_children[1].line_number)
63
+ end
64
+
65
+ def test_profiling_render_tag
66
+ t = Template.parse("{% render 'a_template' %}", profile: true)
67
+ t.render!
68
+
69
+ render_children = t.profiler[0].children
70
+ render_children.each do |timing|
71
+ assert_equal('a_template', timing.partial)
72
+ end
73
+ assert_equal([1, 2], render_children.map(&:line_number))
61
74
  end
62
75
 
63
76
  def test_profiling_times_the_rendering_of_tokens
@@ -65,14 +78,45 @@ class RenderProfilingTest < Minitest::Test
65
78
  t.render!
66
79
 
67
80
  node = t.profiler[0]
68
- refute_nil node.render_time
81
+ refute_nil(node.render_time)
69
82
  end
70
83
 
71
84
  def test_profiling_times_the_entire_render
72
85
  t = Template.parse("{% include 'a_template' %}", profile: true)
73
86
  t.render!
74
87
 
75
- assert t.profiler.total_render_time >= 0, "Total render time was not calculated"
88
+ assert(t.profiler.total_render_time >= 0, "Total render time was not calculated")
89
+ end
90
+
91
+ class SleepTag < Liquid::Tag
92
+ def initialize(tag_name, markup, parse_context)
93
+ super
94
+ @duration = Float(markup)
95
+ end
96
+
97
+ def render_to_output_buffer(_context, _output)
98
+ sleep(@duration)
99
+ end
100
+ end
101
+
102
+ def test_profiling_multiple_renders
103
+ with_custom_tag('sleep', SleepTag) do
104
+ context = Liquid::Context.new
105
+ t = Liquid::Template.parse("{% sleep 0.001 %}", profile: true)
106
+ context.template_name = 'index'
107
+ t.render!(context)
108
+ context.template_name = 'layout'
109
+ first_render_time = context.profiler.total_time
110
+ t.render!(context)
111
+
112
+ profiler = context.profiler
113
+ children = profiler.children
114
+ assert_operator(first_render_time, :>=, 0.001)
115
+ assert_operator(profiler.total_time, :>=, 0.001 + first_render_time)
116
+ assert_equal(["index", "layout"], children.map(&:template_name))
117
+ assert_equal([nil, nil], children.map(&:code))
118
+ assert_equal(profiler.total_time, children.map(&:total_time).reduce(&:+))
119
+ end
76
120
  end
77
121
 
78
122
  def test_profiling_uses_include_to_mark_children
@@ -80,7 +124,7 @@ class RenderProfilingTest < Minitest::Test
80
124
  t.render!
81
125
 
82
126
  include_node = t.profiler[1]
83
- assert_equal 2, include_node.children.length
127
+ assert_equal(2, include_node.children.length)
84
128
  end
85
129
 
86
130
  def test_profiling_marks_children_with_the_name_of_included_partial
@@ -89,7 +133,7 @@ class RenderProfilingTest < Minitest::Test
89
133
 
90
134
  include_node = t.profiler[1]
91
135
  include_node.children.each do |child|
92
- assert_equal "a_template", child.partial
136
+ assert_equal("a_template", child.partial)
93
137
  end
94
138
  end
95
139
 
@@ -99,12 +143,12 @@ class RenderProfilingTest < Minitest::Test
99
143
 
100
144
  a_template = t.profiler[1]
101
145
  a_template.children.each do |child|
102
- assert_equal "a_template", child.partial
146
+ assert_equal("a_template", child.partial)
103
147
  end
104
148
 
105
149
  b_template = t.profiler[2]
106
150
  b_template.children.each do |child|
107
- assert_equal "b_template", child.partial
151
+ assert_equal("b_template", child.partial)
108
152
  end
109
153
  end
110
154
 
@@ -114,12 +158,12 @@ class RenderProfilingTest < Minitest::Test
114
158
 
115
159
  a_template1 = t.profiler[1]
116
160
  a_template1.children.each do |child|
117
- assert_equal "a_template", child.partial
161
+ assert_equal("a_template", child.partial)
118
162
  end
119
163
 
120
164
  a_template2 = t.profiler[2]
121
165
  a_template2.children.each do |child|
122
- assert_equal "a_template", child.partial
166
+ assert_equal("a_template", child.partial)
123
167
  end
124
168
  end
125
169
 
@@ -128,27 +172,42 @@ class RenderProfilingTest < Minitest::Test
128
172
  t.render!
129
173
 
130
174
  timing_count = 0
131
- t.profiler.each do |timing|
175
+ t.profiler.each do |_timing|
132
176
  timing_count += 1
133
177
  end
134
178
 
135
- assert_equal 2, timing_count
179
+ assert_equal(2, timing_count)
136
180
  end
137
181
 
138
182
  def test_profiling_marks_children_of_if_blocks
139
183
  t = Template.parse("{% if true %} {% increment test %} {{ test }} {% endif %}", profile: true)
140
184
  t.render!
141
185
 
142
- assert_equal 1, t.profiler.length
143
- assert_equal 2, t.profiler[0].children.length
186
+ assert_equal(1, t.profiler.length)
187
+ assert_equal(2, t.profiler[0].children.length)
144
188
  end
145
189
 
146
190
  def test_profiling_marks_children_of_for_blocks
147
191
  t = Template.parse("{% for item in collection %} {{ item }} {% endfor %}", profile: true)
148
- t.render!({ "collection" => ["one", "two"] })
192
+ t.render!("collection" => ["one", "two"])
149
193
 
150
- assert_equal 1, t.profiler.length
194
+ assert_equal(1, t.profiler.length)
151
195
  # Will profile each invocation of the for block
152
- assert_equal 2, t.profiler[0].children.length
196
+ assert_equal(2, t.profiler[0].children.length)
197
+ end
198
+
199
+ def test_profiling_supports_self_time
200
+ t = Template.parse("{% for item in collection %} {{ item }} {% endfor %}", profile: true)
201
+ t.render!("collection" => ["one", "two"])
202
+ leaf = t.profiler[0].children[0]
203
+
204
+ assert_operator(leaf.self_time, :>, 0)
205
+ end
206
+
207
+ def test_profiling_supports_total_time
208
+ t = Template.parse("{% if true %} {% increment test %} {{ test }} {% endif %}", profile: true)
209
+ t.render!
210
+
211
+ assert_operator(t.profiler[0].total_time, :>, 0)
153
212
  end
154
213
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  module SecurityFilter
@@ -14,65 +16,72 @@ class SecurityTest < Minitest::Test
14
16
  end
15
17
 
16
18
  def test_no_instance_eval
17
- text = %( {{ '1+1' | instance_eval }} )
19
+ text = %( {{ '1+1' | instance_eval }} )
18
20
  expected = %( 1+1 )
19
21
 
20
- assert_equal expected, Template.parse(text).render!(@assigns)
22
+ assert_equal(expected, Template.parse(text).render!(@assigns))
21
23
  end
22
24
 
23
25
  def test_no_existing_instance_eval
24
- text = %( {{ '1+1' | __instance_eval__ }} )
26
+ text = %( {{ '1+1' | __instance_eval__ }} )
25
27
  expected = %( 1+1 )
26
28
 
27
- assert_equal expected, Template.parse(text).render!(@assigns)
29
+ assert_equal(expected, Template.parse(text).render!(@assigns))
28
30
  end
29
31
 
30
32
  def test_no_instance_eval_after_mixing_in_new_filter
31
- text = %( {{ '1+1' | instance_eval }} )
33
+ text = %( {{ '1+1' | instance_eval }} )
32
34
  expected = %( 1+1 )
33
35
 
34
- assert_equal expected, Template.parse(text).render!(@assigns)
36
+ assert_equal(expected, Template.parse(text).render!(@assigns))
35
37
  end
36
38
 
37
39
  def test_no_instance_eval_later_in_chain
38
- text = %( {{ '1+1' | add_one | instance_eval }} )
40
+ text = %( {{ '1+1' | add_one | instance_eval }} )
39
41
  expected = %( 1+1 + 1 )
40
42
 
41
- assert_equal expected, Template.parse(text).render!(@assigns, filters: SecurityFilter)
43
+ assert_equal(expected, Template.parse(text).render!(@assigns, filters: SecurityFilter))
42
44
  end
43
45
 
44
- def test_does_not_add_filters_to_symbol_table
46
+ def test_does_not_permanently_add_filters_to_symbol_table
45
47
  current_symbols = Symbol.all_symbols
46
48
 
47
- test = %( {{ "some_string" | a_bad_filter }} )
49
+ # MRI imprecisely marks objects found on the C stack, which can result
50
+ # in uninitialized memory being marked. This can even result in the test failing
51
+ # deterministically for a given compilation of ruby. Using a separate thread will
52
+ # keep these writes of the symbol pointer on a separate stack that will be garbage
53
+ # collected after Thread#join.
54
+ Thread.new do
55
+ test = %( {{ "some_string" | a_bad_filter }} )
56
+ Template.parse(test).render!
57
+ nil
58
+ end.join
48
59
 
49
- template = Template.parse(test)
50
- assert_equal [], (Symbol.all_symbols - current_symbols)
60
+ GC.start
51
61
 
52
- template.render!
53
- assert_equal [], (Symbol.all_symbols - current_symbols)
62
+ assert_equal([], (Symbol.all_symbols - current_symbols))
54
63
  end
55
64
 
56
65
  def test_does_not_add_drop_methods_to_symbol_table
57
66
  current_symbols = Symbol.all_symbols
58
67
 
59
68
  assigns = { 'drop' => Drop.new }
60
- assert_equal "", Template.parse("{{ drop.custom_method_1 }}", assigns).render!
61
- assert_equal "", Template.parse("{{ drop.custom_method_2 }}", assigns).render!
62
- assert_equal "", Template.parse("{{ drop.custom_method_3 }}", assigns).render!
69
+ assert_equal("", Template.parse("{{ drop.custom_method_1 }}", assigns).render!)
70
+ assert_equal("", Template.parse("{{ drop.custom_method_2 }}", assigns).render!)
71
+ assert_equal("", Template.parse("{{ drop.custom_method_3 }}", assigns).render!)
63
72
 
64
- assert_equal [], (Symbol.all_symbols - current_symbols)
73
+ assert_equal([], (Symbol.all_symbols - current_symbols))
65
74
  end
66
75
 
67
76
  def test_max_depth_nested_blocks_does_not_raise_exception
68
77
  depth = Liquid::Block::MAX_DEPTH
69
- code = "{% if true %}" * depth + "rendered" + "{% endif %}" * depth
70
- assert_equal "rendered", Template.parse(code).render!
78
+ code = "{% if true %}" * depth + "rendered" + "{% endif %}" * depth
79
+ assert_equal("rendered", Template.parse(code).render!)
71
80
  end
72
81
 
73
82
  def test_more_than_max_depth_nested_blocks_raises_exception
74
83
  depth = Liquid::Block::MAX_DEPTH + 1
75
- code = "{% if true %}" * depth + "rendered" + "{% endif %}" * depth
84
+ code = "{% if true %}" * depth + "rendered" + "{% endif %}" * depth
76
85
  assert_raises(Liquid::StackLevelError) do
77
86
  Template.parse(code).render!
78
87
  end
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'test_helper'
4
5
 
@@ -17,7 +18,7 @@ class TestThing
17
18
  "woot: #{@foo}"
18
19
  end
19
20
 
20
- def [](whatever)
21
+ def [](_whatever)
21
22
  to_s
22
23
  end
23
24
 
@@ -37,7 +38,7 @@ class TestEnumerable < Liquid::Drop
37
38
  include Enumerable
38
39
 
39
40
  def each(&block)
40
- [ { "foo" => 1, "bar" => 2 }, { "foo" => 2, "bar" => 1 }, { "foo" => 3, "bar" => 3 } ].each(&block)
41
+ [{ "foo" => 1, "bar" => 2 }, { "foo" => 2, "bar" => 1 }, { "foo" => 3, "bar" => 3 }].each(&block)
41
42
  end
42
43
  end
43
44
 
@@ -59,34 +60,34 @@ class StandardFiltersTest < Minitest::Test
59
60
  end
60
61
 
61
62
  def test_size
62
- assert_equal 3, @filters.size([1, 2, 3])
63
- assert_equal 0, @filters.size([])
64
- assert_equal 0, @filters.size(nil)
63
+ assert_equal(3, @filters.size([1, 2, 3]))
64
+ assert_equal(0, @filters.size([]))
65
+ assert_equal(0, @filters.size(nil))
65
66
  end
66
67
 
67
68
  def test_downcase
68
- assert_equal 'testing', @filters.downcase("Testing")
69
- assert_equal '', @filters.downcase(nil)
69
+ assert_equal('testing', @filters.downcase("Testing"))
70
+ assert_equal('', @filters.downcase(nil))
70
71
  end
71
72
 
72
73
  def test_upcase
73
- assert_equal 'TESTING', @filters.upcase("Testing")
74
- assert_equal '', @filters.upcase(nil)
74
+ assert_equal('TESTING', @filters.upcase("Testing"))
75
+ assert_equal('', @filters.upcase(nil))
75
76
  end
76
77
 
77
78
  def test_slice
78
- assert_equal 'oob', @filters.slice('foobar', 1, 3)
79
- assert_equal 'oobar', @filters.slice('foobar', 1, 1000)
80
- assert_equal '', @filters.slice('foobar', 1, 0)
81
- assert_equal 'o', @filters.slice('foobar', 1, 1)
82
- assert_equal 'bar', @filters.slice('foobar', 3, 3)
83
- assert_equal 'ar', @filters.slice('foobar', -2, 2)
84
- assert_equal 'ar', @filters.slice('foobar', -2, 1000)
85
- assert_equal 'r', @filters.slice('foobar', -1)
86
- assert_equal '', @filters.slice(nil, 0)
87
- assert_equal '', @filters.slice('foobar', 100, 10)
88
- assert_equal '', @filters.slice('foobar', -100, 10)
89
- assert_equal 'oob', @filters.slice('foobar', '1', '3')
79
+ assert_equal('oob', @filters.slice('foobar', 1, 3))
80
+ assert_equal('oobar', @filters.slice('foobar', 1, 1000))
81
+ assert_equal('', @filters.slice('foobar', 1, 0))
82
+ assert_equal('o', @filters.slice('foobar', 1, 1))
83
+ assert_equal('bar', @filters.slice('foobar', 3, 3))
84
+ assert_equal('ar', @filters.slice('foobar', -2, 2))
85
+ assert_equal('ar', @filters.slice('foobar', -2, 1000))
86
+ assert_equal('r', @filters.slice('foobar', -1))
87
+ assert_equal('', @filters.slice(nil, 0))
88
+ assert_equal('', @filters.slice('foobar', 100, 10))
89
+ assert_equal('', @filters.slice('foobar', -100, 10))
90
+ assert_equal('oob', @filters.slice('foobar', '1', '3'))
90
91
  assert_raises(Liquid::ArgumentError) do
91
92
  @filters.slice('foobar', nil)
92
93
  end
@@ -97,155 +98,161 @@ class StandardFiltersTest < Minitest::Test
97
98
 
98
99
  def test_slice_on_arrays
99
100
  input = 'foobar'.split(//)
100
- assert_equal %w(o o b), @filters.slice(input, 1, 3)
101
- assert_equal %w(o o b a r), @filters.slice(input, 1, 1000)
102
- assert_equal %w(), @filters.slice(input, 1, 0)
103
- assert_equal %w(o), @filters.slice(input, 1, 1)
104
- assert_equal %w(b a r), @filters.slice(input, 3, 3)
105
- assert_equal %w(a r), @filters.slice(input, -2, 2)
106
- assert_equal %w(a r), @filters.slice(input, -2, 1000)
107
- assert_equal %w(r), @filters.slice(input, -1)
108
- assert_equal %w(), @filters.slice(input, 100, 10)
109
- assert_equal %w(), @filters.slice(input, -100, 10)
101
+ assert_equal(%w(o o b), @filters.slice(input, 1, 3))
102
+ assert_equal(%w(o o b a r), @filters.slice(input, 1, 1000))
103
+ assert_equal(%w(), @filters.slice(input, 1, 0))
104
+ assert_equal(%w(o), @filters.slice(input, 1, 1))
105
+ assert_equal(%w(b a r), @filters.slice(input, 3, 3))
106
+ assert_equal(%w(a r), @filters.slice(input, -2, 2))
107
+ assert_equal(%w(a r), @filters.slice(input, -2, 1000))
108
+ assert_equal(%w(r), @filters.slice(input, -1))
109
+ assert_equal(%w(), @filters.slice(input, 100, 10))
110
+ assert_equal(%w(), @filters.slice(input, -100, 10))
110
111
  end
111
112
 
112
113
  def test_truncate
113
- assert_equal '1234...', @filters.truncate('1234567890', 7)
114
- assert_equal '1234567890', @filters.truncate('1234567890', 20)
115
- assert_equal '...', @filters.truncate('1234567890', 0)
116
- assert_equal '1234567890', @filters.truncate('1234567890')
117
- assert_equal "测试...", @filters.truncate("测试测试测试测试", 5)
118
- assert_equal '12341', @filters.truncate("1234567890", 5, 1)
114
+ assert_equal('1234...', @filters.truncate('1234567890', 7))
115
+ assert_equal('1234567890', @filters.truncate('1234567890', 20))
116
+ assert_equal('...', @filters.truncate('1234567890', 0))
117
+ assert_equal('1234567890', @filters.truncate('1234567890'))
118
+ assert_equal("测试...", @filters.truncate("测试测试测试测试", 5))
119
+ assert_equal('12341', @filters.truncate("1234567890", 5, 1))
119
120
  end
120
121
 
121
122
  def test_split
122
- assert_equal ['12', '34'], @filters.split('12~34', '~')
123
- assert_equal ['A? ', ' ,Z'], @filters.split('A? ~ ~ ~ ,Z', '~ ~ ~')
124
- assert_equal ['A?Z'], @filters.split('A?Z', '~')
125
- assert_equal [], @filters.split(nil, ' ')
126
- assert_equal ['A', 'Z'], @filters.split('A1Z', 1)
123
+ assert_equal(['12', '34'], @filters.split('12~34', '~'))
124
+ assert_equal(['A? ', ' ,Z'], @filters.split('A? ~ ~ ~ ,Z', '~ ~ ~'))
125
+ assert_equal(['A?Z'], @filters.split('A?Z', '~'))
126
+ assert_equal([], @filters.split(nil, ' '))
127
+ assert_equal(['A', 'Z'], @filters.split('A1Z', 1))
127
128
  end
128
129
 
129
130
  def test_escape
130
- assert_equal '&lt;strong&gt;', @filters.escape('<strong>')
131
- assert_equal '1', @filters.escape(1)
132
- assert_equal '2001-02-03', @filters.escape(Date.new(2001, 2, 3))
133
- assert_nil @filters.escape(nil)
131
+ assert_equal('&lt;strong&gt;', @filters.escape('<strong>'))
132
+ assert_equal('1', @filters.escape(1))
133
+ assert_equal('2001-02-03', @filters.escape(Date.new(2001, 2, 3)))
134
+ assert_nil(@filters.escape(nil))
134
135
  end
135
136
 
136
137
  def test_h
137
- assert_equal '&lt;strong&gt;', @filters.h('<strong>')
138
- assert_equal '1', @filters.h(1)
139
- assert_equal '2001-02-03', @filters.h(Date.new(2001, 2, 3))
140
- assert_nil @filters.h(nil)
138
+ assert_equal('&lt;strong&gt;', @filters.h('<strong>'))
139
+ assert_equal('1', @filters.h(1))
140
+ assert_equal('2001-02-03', @filters.h(Date.new(2001, 2, 3)))
141
+ assert_nil(@filters.h(nil))
141
142
  end
142
143
 
143
144
  def test_escape_once
144
- assert_equal '&lt;strong&gt;Hulk&lt;/strong&gt;', @filters.escape_once('&lt;strong&gt;Hulk</strong>')
145
+ assert_equal('&lt;strong&gt;Hulk&lt;/strong&gt;', @filters.escape_once('&lt;strong&gt;Hulk</strong>'))
145
146
  end
146
147
 
147
148
  def test_url_encode
148
- assert_equal 'foo%2B1%40example.com', @filters.url_encode('foo+1@example.com')
149
- assert_equal '1', @filters.url_encode(1)
150
- assert_equal '2001-02-03', @filters.url_encode(Date.new(2001, 2, 3))
151
- assert_nil @filters.url_encode(nil)
149
+ assert_equal('foo%2B1%40example.com', @filters.url_encode('foo+1@example.com'))
150
+ assert_equal('1', @filters.url_encode(1))
151
+ assert_equal('2001-02-03', @filters.url_encode(Date.new(2001, 2, 3)))
152
+ assert_nil(@filters.url_encode(nil))
152
153
  end
153
154
 
154
155
  def test_url_decode
155
- assert_equal 'foo bar', @filters.url_decode('foo+bar')
156
- assert_equal 'foo bar', @filters.url_decode('foo%20bar')
157
- assert_equal 'foo+1@example.com', @filters.url_decode('foo%2B1%40example.com')
158
- assert_equal '1', @filters.url_decode(1)
159
- assert_equal '2001-02-03', @filters.url_decode(Date.new(2001, 2, 3))
160
- assert_nil @filters.url_decode(nil)
161
- exception = assert_raises Liquid::ArgumentError do
156
+ assert_equal('foo bar', @filters.url_decode('foo+bar'))
157
+ assert_equal('foo bar', @filters.url_decode('foo%20bar'))
158
+ assert_equal('foo+1@example.com', @filters.url_decode('foo%2B1%40example.com'))
159
+ assert_equal('1', @filters.url_decode(1))
160
+ assert_equal('2001-02-03', @filters.url_decode(Date.new(2001, 2, 3)))
161
+ assert_nil(@filters.url_decode(nil))
162
+ exception = assert_raises(Liquid::ArgumentError) do
162
163
  @filters.url_decode('%ff')
163
164
  end
164
- assert_equal 'Liquid error: invalid byte sequence in UTF-8', exception.message
165
+ assert_equal('Liquid error: invalid byte sequence in UTF-8', exception.message)
165
166
  end
166
167
 
167
168
  def test_truncatewords
168
- assert_equal 'one two three', @filters.truncatewords('one two three', 4)
169
- assert_equal 'one two...', @filters.truncatewords('one two three', 2)
170
- assert_equal 'one two three', @filters.truncatewords('one two three')
171
- assert_equal 'Two small (13&#8221; x 5.5&#8221; x 10&#8221; high) baskets fit inside one large basket (13&#8221;...', @filters.truncatewords('Two small (13&#8221; x 5.5&#8221; x 10&#8221; high) baskets fit inside one large basket (13&#8221; x 16&#8221; x 10.5&#8221; high) with cover.', 15)
172
- assert_equal "测试测试测试测试", @filters.truncatewords('测试测试测试测试', 5)
173
- assert_equal 'one two1', @filters.truncatewords("one two three", 2, 1)
169
+ assert_equal('one two three', @filters.truncatewords('one two three', 4))
170
+ assert_equal('one two...', @filters.truncatewords('one two three', 2))
171
+ assert_equal('one two three', @filters.truncatewords('one two three'))
172
+ assert_equal(
173
+ 'Two small (13&#8221; x 5.5&#8221; x 10&#8221; high) baskets fit inside one large basket (13&#8221;...',
174
+ @filters.truncatewords('Two small (13&#8221; x 5.5&#8221; x 10&#8221; high) baskets fit inside one large basket (13&#8221; x 16&#8221; x 10.5&#8221; high) with cover.', 15)
175
+ )
176
+ assert_equal("测试测试测试测试", @filters.truncatewords('测试测试测试测试', 5))
177
+ assert_equal('one two1', @filters.truncatewords("one two three", 2, 1))
178
+ assert_equal('one two three...', @filters.truncatewords("one two\tthree\nfour", 3))
179
+ assert_equal('one two...', @filters.truncatewords("one two three four", 2))
180
+ assert_equal('one...', @filters.truncatewords("one two three four", 0))
174
181
  end
175
182
 
176
183
  def test_strip_html
177
- assert_equal 'test', @filters.strip_html("<div>test</div>")
178
- assert_equal 'test', @filters.strip_html("<div id='test'>test</div>")
179
- assert_equal '', @filters.strip_html("<script type='text/javascript'>document.write('some stuff');</script>")
180
- assert_equal '', @filters.strip_html("<style type='text/css'>foo bar</style>")
181
- assert_equal 'test', @filters.strip_html("<div\nclass='multiline'>test</div>")
182
- assert_equal 'test', @filters.strip_html("<!-- foo bar \n test -->test")
183
- assert_equal '', @filters.strip_html(nil)
184
+ assert_equal('test', @filters.strip_html("<div>test</div>"))
185
+ assert_equal('test', @filters.strip_html("<div id='test'>test</div>"))
186
+ assert_equal('', @filters.strip_html("<script type='text/javascript'>document.write('some stuff');</script>"))
187
+ assert_equal('', @filters.strip_html("<style type='text/css'>foo bar</style>"))
188
+ assert_equal('test', @filters.strip_html("<div\nclass='multiline'>test</div>"))
189
+ assert_equal('test', @filters.strip_html("<!-- foo bar \n test -->test"))
190
+ assert_equal('', @filters.strip_html(nil))
184
191
 
185
192
  # Quirk of the existing implementation
186
- assert_equal 'foo;', @filters.strip_html("<<<script </script>script>foo;</script>")
193
+ assert_equal('foo;', @filters.strip_html("<<<script </script>script>foo;</script>"))
187
194
  end
188
195
 
189
196
  def test_join
190
- assert_equal '1 2 3 4', @filters.join([1, 2, 3, 4])
191
- assert_equal '1 - 2 - 3 - 4', @filters.join([1, 2, 3, 4], ' - ')
192
- assert_equal '1121314', @filters.join([1, 2, 3, 4], 1)
197
+ assert_equal('1 2 3 4', @filters.join([1, 2, 3, 4]))
198
+ assert_equal('1 - 2 - 3 - 4', @filters.join([1, 2, 3, 4], ' - '))
199
+ assert_equal('1121314', @filters.join([1, 2, 3, 4], 1))
193
200
  end
194
201
 
195
202
  def test_sort
196
- assert_equal [1, 2, 3, 4], @filters.sort([4, 3, 2, 1])
197
- assert_equal [{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }], @filters.sort([{ "a" => 4 }, { "a" => 3 }, { "a" => 1 }, { "a" => 2 }], "a")
203
+ assert_equal([1, 2, 3, 4], @filters.sort([4, 3, 2, 1]))
204
+ assert_equal([{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }], @filters.sort([{ "a" => 4 }, { "a" => 3 }, { "a" => 1 }, { "a" => 2 }], "a"))
198
205
  end
199
206
 
200
207
  def test_sort_with_nils
201
- assert_equal [1, 2, 3, 4, nil], @filters.sort([nil, 4, 3, 2, 1])
202
- assert_equal [{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }, {}], @filters.sort([{ "a" => 4 }, { "a" => 3 }, {}, { "a" => 1 }, { "a" => 2 }], "a")
208
+ assert_equal([1, 2, 3, 4, nil], @filters.sort([nil, 4, 3, 2, 1]))
209
+ assert_equal([{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }, {}], @filters.sort([{ "a" => 4 }, { "a" => 3 }, {}, { "a" => 1 }, { "a" => 2 }], "a"))
203
210
  end
204
211
 
205
212
  def test_sort_when_property_is_sometimes_missing_puts_nils_last
206
- input = [
213
+ input = [
207
214
  { "price" => 4, "handle" => "alpha" },
208
215
  { "handle" => "beta" },
209
216
  { "price" => 1, "handle" => "gamma" },
210
217
  { "handle" => "delta" },
211
- { "price" => 2, "handle" => "epsilon" }
218
+ { "price" => 2, "handle" => "epsilon" },
212
219
  ]
213
220
  expectation = [
214
221
  { "price" => 1, "handle" => "gamma" },
215
222
  { "price" => 2, "handle" => "epsilon" },
216
223
  { "price" => 4, "handle" => "alpha" },
217
224
  { "handle" => "delta" },
218
- { "handle" => "beta" }
225
+ { "handle" => "beta" },
219
226
  ]
220
- assert_equal expectation, @filters.sort(input, "price")
227
+ assert_equal(expectation, @filters.sort(input, "price"))
221
228
  end
222
229
 
223
230
  def test_sort_natural
224
- assert_equal ["a", "B", "c", "D"], @filters.sort_natural(["c", "D", "a", "B"])
225
- assert_equal [{ "a" => "a" }, { "a" => "B" }, { "a" => "c" }, { "a" => "D" }], @filters.sort_natural([{ "a" => "D" }, { "a" => "c" }, { "a" => "a" }, { "a" => "B" }], "a")
231
+ assert_equal(["a", "B", "c", "D"], @filters.sort_natural(["c", "D", "a", "B"]))
232
+ assert_equal([{ "a" => "a" }, { "a" => "B" }, { "a" => "c" }, { "a" => "D" }], @filters.sort_natural([{ "a" => "D" }, { "a" => "c" }, { "a" => "a" }, { "a" => "B" }], "a"))
226
233
  end
227
234
 
228
235
  def test_sort_natural_with_nils
229
- assert_equal ["a", "B", "c", "D", nil], @filters.sort_natural([nil, "c", "D", "a", "B"])
230
- assert_equal [{ "a" => "a" }, { "a" => "B" }, { "a" => "c" }, { "a" => "D" }, {}], @filters.sort_natural([{ "a" => "D" }, { "a" => "c" }, {}, { "a" => "a" }, { "a" => "B" }], "a")
236
+ assert_equal(["a", "B", "c", "D", nil], @filters.sort_natural([nil, "c", "D", "a", "B"]))
237
+ assert_equal([{ "a" => "a" }, { "a" => "B" }, { "a" => "c" }, { "a" => "D" }, {}], @filters.sort_natural([{ "a" => "D" }, { "a" => "c" }, {}, { "a" => "a" }, { "a" => "B" }], "a"))
231
238
  end
232
239
 
233
240
  def test_sort_natural_when_property_is_sometimes_missing_puts_nils_last
234
- input = [
241
+ input = [
235
242
  { "price" => "4", "handle" => "alpha" },
236
243
  { "handle" => "beta" },
237
244
  { "price" => "1", "handle" => "gamma" },
238
245
  { "handle" => "delta" },
239
- { "price" => 2, "handle" => "epsilon" }
246
+ { "price" => 2, "handle" => "epsilon" },
240
247
  ]
241
248
  expectation = [
242
249
  { "price" => "1", "handle" => "gamma" },
243
250
  { "price" => 2, "handle" => "epsilon" },
244
251
  { "price" => "4", "handle" => "alpha" },
245
252
  { "handle" => "delta" },
246
- { "handle" => "beta" }
253
+ { "handle" => "beta" },
247
254
  ]
248
- assert_equal expectation, @filters.sort_natural(input, "price")
255
+ assert_equal(expectation, @filters.sort_natural(input, "price"))
249
256
  end
250
257
 
251
258
  def test_sort_natural_case_check
@@ -256,7 +263,7 @@ class StandardFiltersTest < Minitest::Test
256
263
  { "fake" => "t" },
257
264
  { "key" => "a" },
258
265
  { "key" => "b" },
259
- { "key" => "c" }
266
+ { "key" => "c" },
260
267
  ]
261
268
  expectation = [
262
269
  { "key" => "a" },
@@ -265,168 +272,168 @@ class StandardFiltersTest < Minitest::Test
265
272
  { "key" => "X" },
266
273
  { "key" => "Y" },
267
274
  { "key" => "Z" },
268
- { "fake" => "t" }
275
+ { "fake" => "t" },
269
276
  ]
270
- assert_equal expectation, @filters.sort_natural(input, "key")
271
- assert_equal ["a", "b", "c", "X", "Y", "Z"], @filters.sort_natural(["X", "Y", "Z", "a", "b", "c"])
277
+ assert_equal(expectation, @filters.sort_natural(input, "key"))
278
+ assert_equal(["a", "b", "c", "X", "Y", "Z"], @filters.sort_natural(["X", "Y", "Z", "a", "b", "c"]))
272
279
  end
273
280
 
274
281
  def test_sort_empty_array
275
- assert_equal [], @filters.sort([], "a")
282
+ assert_equal([], @filters.sort([], "a"))
276
283
  end
277
284
 
278
285
  def test_sort_invalid_property
279
286
  foo = [
280
287
  [1],
281
288
  [2],
282
- [3]
289
+ [3],
283
290
  ]
284
291
 
285
- assert_raises Liquid::ArgumentError do
292
+ assert_raises(Liquid::ArgumentError) do
286
293
  @filters.sort(foo, "bar")
287
294
  end
288
295
  end
289
296
 
290
297
  def test_sort_natural_empty_array
291
- assert_equal [], @filters.sort_natural([], "a")
298
+ assert_equal([], @filters.sort_natural([], "a"))
292
299
  end
293
300
 
294
301
  def test_sort_natural_invalid_property
295
302
  foo = [
296
303
  [1],
297
304
  [2],
298
- [3]
305
+ [3],
299
306
  ]
300
307
 
301
- assert_raises Liquid::ArgumentError do
308
+ assert_raises(Liquid::ArgumentError) do
302
309
  @filters.sort_natural(foo, "bar")
303
310
  end
304
311
  end
305
312
 
306
313
  def test_legacy_sort_hash
307
- assert_equal [{ a: 1, b: 2 }], @filters.sort({ a: 1, b: 2 })
314
+ assert_equal([{ a: 1, b: 2 }], @filters.sort(a: 1, b: 2))
308
315
  end
309
316
 
310
317
  def test_numerical_vs_lexicographical_sort
311
- assert_equal [2, 10], @filters.sort([10, 2])
312
- assert_equal [{ "a" => 2 }, { "a" => 10 }], @filters.sort([{ "a" => 10 }, { "a" => 2 }], "a")
313
- assert_equal ["10", "2"], @filters.sort(["10", "2"])
314
- assert_equal [{ "a" => "10" }, { "a" => "2" }], @filters.sort([{ "a" => "10" }, { "a" => "2" }], "a")
318
+ assert_equal([2, 10], @filters.sort([10, 2]))
319
+ assert_equal([{ "a" => 2 }, { "a" => 10 }], @filters.sort([{ "a" => 10 }, { "a" => 2 }], "a"))
320
+ assert_equal(["10", "2"], @filters.sort(["10", "2"]))
321
+ assert_equal([{ "a" => "10" }, { "a" => "2" }], @filters.sort([{ "a" => "10" }, { "a" => "2" }], "a"))
315
322
  end
316
323
 
317
324
  def test_uniq
318
- assert_equal ["foo"], @filters.uniq("foo")
319
- assert_equal [1, 3, 2, 4], @filters.uniq([1, 1, 3, 2, 3, 1, 4, 3, 2, 1])
320
- assert_equal [{ "a" => 1 }, { "a" => 3 }, { "a" => 2 }], @filters.uniq([{ "a" => 1 }, { "a" => 3 }, { "a" => 1 }, { "a" => 2 }], "a")
325
+ assert_equal(["foo"], @filters.uniq("foo"))
326
+ assert_equal([1, 3, 2, 4], @filters.uniq([1, 1, 3, 2, 3, 1, 4, 3, 2, 1]))
327
+ assert_equal([{ "a" => 1 }, { "a" => 3 }, { "a" => 2 }], @filters.uniq([{ "a" => 1 }, { "a" => 3 }, { "a" => 1 }, { "a" => 2 }], "a"))
321
328
  testdrop = TestDrop.new
322
- assert_equal [testdrop], @filters.uniq([testdrop, TestDrop.new], 'test')
329
+ assert_equal([testdrop], @filters.uniq([testdrop, TestDrop.new], 'test'))
323
330
  end
324
331
 
325
332
  def test_uniq_empty_array
326
- assert_equal [], @filters.uniq([], "a")
333
+ assert_equal([], @filters.uniq([], "a"))
327
334
  end
328
335
 
329
336
  def test_uniq_invalid_property
330
337
  foo = [
331
338
  [1],
332
339
  [2],
333
- [3]
340
+ [3],
334
341
  ]
335
342
 
336
- assert_raises Liquid::ArgumentError do
343
+ assert_raises(Liquid::ArgumentError) do
337
344
  @filters.uniq(foo, "bar")
338
345
  end
339
346
  end
340
347
 
341
348
  def test_compact_empty_array
342
- assert_equal [], @filters.compact([], "a")
349
+ assert_equal([], @filters.compact([], "a"))
343
350
  end
344
351
 
345
352
  def test_compact_invalid_property
346
353
  foo = [
347
354
  [1],
348
355
  [2],
349
- [3]
356
+ [3],
350
357
  ]
351
358
 
352
- assert_raises Liquid::ArgumentError do
359
+ assert_raises(Liquid::ArgumentError) do
353
360
  @filters.compact(foo, "bar")
354
361
  end
355
362
  end
356
363
 
357
364
  def test_reverse
358
- assert_equal [4, 3, 2, 1], @filters.reverse([1, 2, 3, 4])
365
+ assert_equal([4, 3, 2, 1], @filters.reverse([1, 2, 3, 4]))
359
366
  end
360
367
 
361
368
  def test_legacy_reverse_hash
362
- assert_equal [{ a: 1, b: 2 }], @filters.reverse(a: 1, b: 2)
369
+ assert_equal([{ a: 1, b: 2 }], @filters.reverse(a: 1, b: 2))
363
370
  end
364
371
 
365
372
  def test_map
366
- assert_equal [1, 2, 3, 4], @filters.map([{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }], 'a')
367
- assert_template_result 'abc', "{{ ary | map:'foo' | map:'bar' }}",
368
- 'ary' => [{ 'foo' => { 'bar' => 'a' } }, { 'foo' => { 'bar' => 'b' } }, { 'foo' => { 'bar' => 'c' } }]
373
+ assert_equal([1, 2, 3, 4], @filters.map([{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }], 'a'))
374
+ assert_template_result('abc', "{{ ary | map:'foo' | map:'bar' }}",
375
+ 'ary' => [{ 'foo' => { 'bar' => 'a' } }, { 'foo' => { 'bar' => 'b' } }, { 'foo' => { 'bar' => 'c' } }])
369
376
  end
370
377
 
371
378
  def test_map_doesnt_call_arbitrary_stuff
372
- assert_template_result "", '{{ "foo" | map: "__id__" }}'
373
- assert_template_result "", '{{ "foo" | map: "inspect" }}'
379
+ assert_template_result("", '{{ "foo" | map: "__id__" }}')
380
+ assert_template_result("", '{{ "foo" | map: "inspect" }}')
374
381
  end
375
382
 
376
383
  def test_map_calls_to_liquid
377
384
  t = TestThing.new
378
- assert_template_result "woot: 1", '{{ foo | map: "whatever" }}', "foo" => [t]
385
+ assert_template_result("woot: 1", '{{ foo | map: "whatever" }}', "foo" => [t])
379
386
  end
380
387
 
381
388
  def test_map_on_hashes
382
- assert_template_result "4217", '{{ thing | map: "foo" | map: "bar" }}',
383
- "thing" => { "foo" => [ { "bar" => 42 }, { "bar" => 17 } ] }
389
+ assert_template_result("4217", '{{ thing | map: "foo" | map: "bar" }}',
390
+ "thing" => { "foo" => [{ "bar" => 42 }, { "bar" => 17 }] })
384
391
  end
385
392
 
386
393
  def test_legacy_map_on_hashes_with_dynamic_key
387
394
  template = "{% assign key = 'foo' %}{{ thing | map: key | map: 'bar' }}"
388
- hash = { "foo" => { "bar" => 42 } }
389
- assert_template_result "42", template, "thing" => hash
395
+ hash = { "foo" => { "bar" => 42 } }
396
+ assert_template_result("42", template, "thing" => hash)
390
397
  end
391
398
 
392
399
  def test_sort_calls_to_liquid
393
400
  t = TestThing.new
394
401
  Liquid::Template.parse('{{ foo | sort: "whatever" }}').render("foo" => [t])
395
- assert t.foo > 0
402
+ assert(t.foo > 0)
396
403
  end
397
404
 
398
405
  def test_map_over_proc
399
- drop = TestDrop.new
400
- p = proc{ drop }
406
+ drop = TestDrop.new
407
+ p = proc { drop }
401
408
  templ = '{{ procs | map: "test" }}'
402
- assert_template_result "testfoo", templ, "procs" => [p]
409
+ assert_template_result("testfoo", templ, "procs" => [p])
403
410
  end
404
411
 
405
412
  def test_map_over_drops_returning_procs
406
413
  drops = [
407
414
  {
408
- "proc" => ->{ "foo" },
415
+ "proc" => -> { "foo" },
409
416
  },
410
417
  {
411
- "proc" => ->{ "bar" },
418
+ "proc" => -> { "bar" },
412
419
  },
413
420
  ]
414
421
  templ = '{{ drops | map: "proc" }}'
415
- assert_template_result "foobar", templ, "drops" => drops
422
+ assert_template_result("foobar", templ, "drops" => drops)
416
423
  end
417
424
 
418
425
  def test_map_works_on_enumerables
419
- assert_template_result "123", '{{ foo | map: "foo" }}', "foo" => TestEnumerable.new
426
+ assert_template_result("123", '{{ foo | map: "foo" }}', "foo" => TestEnumerable.new)
420
427
  end
421
428
 
422
429
  def test_map_returns_empty_on_2d_input_array
423
430
  foo = [
424
431
  [1],
425
432
  [2],
426
- [3]
433
+ [3],
427
434
  ]
428
435
 
429
- assert_raises Liquid::ArgumentError do
436
+ assert_raises(Liquid::ArgumentError) do
430
437
  @filters.map(foo, "bar")
431
438
  end
432
439
  end
@@ -435,221 +442,222 @@ class StandardFiltersTest < Minitest::Test
435
442
  foo = [
436
443
  [1],
437
444
  [2],
438
- [3]
445
+ [3],
439
446
  ]
440
- assert_raises Liquid::ArgumentError do
447
+ assert_raises(Liquid::ArgumentError) do
441
448
  @filters.map(foo, nil)
442
449
  end
443
450
  end
444
451
 
445
452
  def test_sort_works_on_enumerables
446
- assert_template_result "213", '{{ foo | sort: "bar" | map: "foo" }}', "foo" => TestEnumerable.new
453
+ assert_template_result("213", '{{ foo | sort: "bar" | map: "foo" }}', "foo" => TestEnumerable.new)
447
454
  end
448
455
 
449
456
  def test_first_and_last_call_to_liquid
450
- assert_template_result 'foobar', '{{ foo | first }}', 'foo' => [ThingWithToLiquid.new]
451
- assert_template_result 'foobar', '{{ foo | last }}', 'foo' => [ThingWithToLiquid.new]
457
+ assert_template_result('foobar', '{{ foo | first }}', 'foo' => [ThingWithToLiquid.new])
458
+ assert_template_result('foobar', '{{ foo | last }}', 'foo' => [ThingWithToLiquid.new])
452
459
  end
453
460
 
454
461
  def test_truncate_calls_to_liquid
455
- assert_template_result "wo...", '{{ foo | truncate: 5 }}', "foo" => TestThing.new
462
+ assert_template_result("wo...", '{{ foo | truncate: 5 }}', "foo" => TestThing.new)
456
463
  end
457
464
 
458
465
  def test_date
459
- assert_equal 'May', @filters.date(Time.parse("2006-05-05 10:00:00"), "%B")
460
- assert_equal 'June', @filters.date(Time.parse("2006-06-05 10:00:00"), "%B")
461
- assert_equal 'July', @filters.date(Time.parse("2006-07-05 10:00:00"), "%B")
466
+ assert_equal('May', @filters.date(Time.parse("2006-05-05 10:00:00"), "%B"))
467
+ assert_equal('June', @filters.date(Time.parse("2006-06-05 10:00:00"), "%B"))
468
+ assert_equal('July', @filters.date(Time.parse("2006-07-05 10:00:00"), "%B"))
462
469
 
463
- assert_equal 'May', @filters.date("2006-05-05 10:00:00", "%B")
464
- assert_equal 'June', @filters.date("2006-06-05 10:00:00", "%B")
465
- assert_equal 'July', @filters.date("2006-07-05 10:00:00", "%B")
470
+ assert_equal('May', @filters.date("2006-05-05 10:00:00", "%B"))
471
+ assert_equal('June', @filters.date("2006-06-05 10:00:00", "%B"))
472
+ assert_equal('July', @filters.date("2006-07-05 10:00:00", "%B"))
466
473
 
467
- assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", "")
468
- assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", "")
469
- assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", "")
470
- assert_equal '2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", nil)
474
+ assert_equal('2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", ""))
475
+ assert_equal('2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", ""))
476
+ assert_equal('2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", ""))
477
+ assert_equal('2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", nil))
471
478
 
472
- assert_equal '07/05/2006', @filters.date("2006-07-05 10:00:00", "%m/%d/%Y")
479
+ assert_equal('07/05/2006', @filters.date("2006-07-05 10:00:00", "%m/%d/%Y"))
473
480
 
474
- assert_equal "07/16/2004", @filters.date("Fri Jul 16 01:00:00 2004", "%m/%d/%Y")
475
- assert_equal Date.today.year.to_s, @filters.date('now', '%Y')
476
- assert_equal Date.today.year.to_s, @filters.date('today', '%Y')
477
- assert_equal Date.today.year.to_s, @filters.date('Today', '%Y')
481
+ assert_equal("07/16/2004", @filters.date("Fri Jul 16 01:00:00 2004", "%m/%d/%Y"))
482
+ assert_equal(Date.today.year.to_s, @filters.date('now', '%Y'))
483
+ assert_equal(Date.today.year.to_s, @filters.date('today', '%Y'))
484
+ assert_equal(Date.today.year.to_s, @filters.date('Today', '%Y'))
478
485
 
479
- assert_nil @filters.date(nil, "%B")
486
+ assert_nil(@filters.date(nil, "%B"))
480
487
 
481
- assert_equal '', @filters.date('', "%B")
488
+ assert_equal('', @filters.date('', "%B"))
482
489
 
483
490
  with_timezone("UTC") do
484
- assert_equal "07/05/2006", @filters.date(1152098955, "%m/%d/%Y")
485
- assert_equal "07/05/2006", @filters.date("1152098955", "%m/%d/%Y")
491
+ assert_equal("07/05/2006", @filters.date(1152098955, "%m/%d/%Y"))
492
+ assert_equal("07/05/2006", @filters.date("1152098955", "%m/%d/%Y"))
486
493
  end
487
494
  end
488
495
 
489
496
  def test_first_last
490
- assert_equal 1, @filters.first([1, 2, 3])
491
- assert_equal 3, @filters.last([1, 2, 3])
492
- assert_nil @filters.first([])
493
- assert_nil @filters.last([])
497
+ assert_equal(1, @filters.first([1, 2, 3]))
498
+ assert_equal(3, @filters.last([1, 2, 3]))
499
+ assert_nil(@filters.first([]))
500
+ assert_nil(@filters.last([]))
494
501
  end
495
502
 
496
503
  def test_replace
497
- assert_equal '2 2 2 2', @filters.replace('1 1 1 1', '1', 2)
498
- assert_equal '2 2 2 2', @filters.replace('1 1 1 1', 1, 2)
499
- assert_equal '2 1 1 1', @filters.replace_first('1 1 1 1', '1', 2)
500
- assert_equal '2 1 1 1', @filters.replace_first('1 1 1 1', 1, 2)
501
- assert_template_result '2 1 1 1', "{{ '1 1 1 1' | replace_first: '1', 2 }}"
504
+ assert_equal('2 2 2 2', @filters.replace('1 1 1 1', '1', 2))
505
+ assert_equal('2 2 2 2', @filters.replace('1 1 1 1', 1, 2))
506
+ assert_equal('2 1 1 1', @filters.replace_first('1 1 1 1', '1', 2))
507
+ assert_equal('2 1 1 1', @filters.replace_first('1 1 1 1', 1, 2))
508
+ assert_template_result('2 1 1 1', "{{ '1 1 1 1' | replace_first: '1', 2 }}")
502
509
  end
503
510
 
504
511
  def test_remove
505
- assert_equal ' ', @filters.remove("a a a a", 'a')
506
- assert_equal ' ', @filters.remove("1 1 1 1", 1)
507
- assert_equal 'a a a', @filters.remove_first("a a a a", 'a ')
508
- assert_equal ' 1 1 1', @filters.remove_first("1 1 1 1", 1)
509
- assert_template_result 'a a a', "{{ 'a a a a' | remove_first: 'a ' }}"
512
+ assert_equal(' ', @filters.remove("a a a a", 'a'))
513
+ assert_equal(' ', @filters.remove("1 1 1 1", 1))
514
+ assert_equal('a a a', @filters.remove_first("a a a a", 'a '))
515
+ assert_equal(' 1 1 1', @filters.remove_first("1 1 1 1", 1))
516
+ assert_template_result('a a a', "{{ 'a a a a' | remove_first: 'a ' }}")
510
517
  end
511
518
 
512
519
  def test_pipes_in_string_arguments
513
- assert_template_result 'foobar', "{{ 'foo|bar' | remove: '|' }}"
520
+ assert_template_result('foobar', "{{ 'foo|bar' | remove: '|' }}")
514
521
  end
515
522
 
516
523
  def test_strip
517
- assert_template_result 'ab c', "{{ source | strip }}", 'source' => " ab c "
518
- assert_template_result 'ab c', "{{ source | strip }}", 'source' => " \tab c \n \t"
524
+ assert_template_result('ab c', "{{ source | strip }}", 'source' => " ab c ")
525
+ assert_template_result('ab c', "{{ source | strip }}", 'source' => " \tab c \n \t")
519
526
  end
520
527
 
521
528
  def test_lstrip
522
- assert_template_result 'ab c ', "{{ source | lstrip }}", 'source' => " ab c "
523
- assert_template_result "ab c \n \t", "{{ source | lstrip }}", 'source' => " \tab c \n \t"
529
+ assert_template_result('ab c ', "{{ source | lstrip }}", 'source' => " ab c ")
530
+ assert_template_result("ab c \n \t", "{{ source | lstrip }}", 'source' => " \tab c \n \t")
524
531
  end
525
532
 
526
533
  def test_rstrip
527
- assert_template_result " ab c", "{{ source | rstrip }}", 'source' => " ab c "
528
- assert_template_result " \tab c", "{{ source | rstrip }}", 'source' => " \tab c \n \t"
534
+ assert_template_result(" ab c", "{{ source | rstrip }}", 'source' => " ab c ")
535
+ assert_template_result(" \tab c", "{{ source | rstrip }}", 'source' => " \tab c \n \t")
529
536
  end
530
537
 
531
538
  def test_strip_newlines
532
- assert_template_result 'abc', "{{ source | strip_newlines }}", 'source' => "a\nb\nc"
533
- assert_template_result 'abc', "{{ source | strip_newlines }}", 'source' => "a\r\nb\nc"
539
+ assert_template_result('abc', "{{ source | strip_newlines }}", 'source' => "a\nb\nc")
540
+ assert_template_result('abc', "{{ source | strip_newlines }}", 'source' => "a\r\nb\nc")
534
541
  end
535
542
 
536
543
  def test_newlines_to_br
537
- assert_template_result "a<br />\nb<br />\nc", "{{ source | newline_to_br }}", 'source' => "a\nb\nc"
544
+ assert_template_result("a<br />\nb<br />\nc", "{{ source | newline_to_br }}", 'source' => "a\nb\nc")
545
+ assert_template_result("a<br />\nb<br />\nc", "{{ source | newline_to_br }}", 'source' => "a\r\nb\nc")
538
546
  end
539
547
 
540
548
  def test_plus
541
- assert_template_result "2", "{{ 1 | plus:1 }}"
542
- assert_template_result "2.0", "{{ '1' | plus:'1.0' }}"
549
+ assert_template_result("2", "{{ 1 | plus:1 }}")
550
+ assert_template_result("2.0", "{{ '1' | plus:'1.0' }}")
543
551
 
544
- assert_template_result "5", "{{ price | plus:'2' }}", 'price' => NumberLikeThing.new(3)
552
+ assert_template_result("5", "{{ price | plus:'2' }}", 'price' => NumberLikeThing.new(3))
545
553
  end
546
554
 
547
555
  def test_minus
548
- assert_template_result "4", "{{ input | minus:operand }}", 'input' => 5, 'operand' => 1
549
- assert_template_result "2.3", "{{ '4.3' | minus:'2' }}"
556
+ assert_template_result("4", "{{ input | minus:operand }}", 'input' => 5, 'operand' => 1)
557
+ assert_template_result("2.3", "{{ '4.3' | minus:'2' }}")
550
558
 
551
- assert_template_result "5", "{{ price | minus:'2' }}", 'price' => NumberLikeThing.new(7)
559
+ assert_template_result("5", "{{ price | minus:'2' }}", 'price' => NumberLikeThing.new(7))
552
560
  end
553
561
 
554
562
  def test_abs
555
- assert_template_result "17", "{{ 17 | abs }}"
556
- assert_template_result "17", "{{ -17 | abs }}"
557
- assert_template_result "17", "{{ '17' | abs }}"
558
- assert_template_result "17", "{{ '-17' | abs }}"
559
- assert_template_result "0", "{{ 0 | abs }}"
560
- assert_template_result "0", "{{ '0' | abs }}"
561
- assert_template_result "17.42", "{{ 17.42 | abs }}"
562
- assert_template_result "17.42", "{{ -17.42 | abs }}"
563
- assert_template_result "17.42", "{{ '17.42' | abs }}"
564
- assert_template_result "17.42", "{{ '-17.42' | abs }}"
563
+ assert_template_result("17", "{{ 17 | abs }}")
564
+ assert_template_result("17", "{{ -17 | abs }}")
565
+ assert_template_result("17", "{{ '17' | abs }}")
566
+ assert_template_result("17", "{{ '-17' | abs }}")
567
+ assert_template_result("0", "{{ 0 | abs }}")
568
+ assert_template_result("0", "{{ '0' | abs }}")
569
+ assert_template_result("17.42", "{{ 17.42 | abs }}")
570
+ assert_template_result("17.42", "{{ -17.42 | abs }}")
571
+ assert_template_result("17.42", "{{ '17.42' | abs }}")
572
+ assert_template_result("17.42", "{{ '-17.42' | abs }}")
565
573
  end
566
574
 
567
575
  def test_times
568
- assert_template_result "12", "{{ 3 | times:4 }}"
569
- assert_template_result "0", "{{ 'foo' | times:4 }}"
570
- assert_template_result "6", "{{ '2.1' | times:3 | replace: '.','-' | plus:0}}"
571
- assert_template_result "7.25", "{{ 0.0725 | times:100 }}"
572
- assert_template_result "-7.25", '{{ "-0.0725" | times:100 }}'
573
- assert_template_result "7.25", '{{ "-0.0725" | times: -100 }}'
574
- assert_template_result "4", "{{ price | times:2 }}", 'price' => NumberLikeThing.new(2)
576
+ assert_template_result("12", "{{ 3 | times:4 }}")
577
+ assert_template_result("0", "{{ 'foo' | times:4 }}")
578
+ assert_template_result("6", "{{ '2.1' | times:3 | replace: '.','-' | plus:0}}")
579
+ assert_template_result("7.25", "{{ 0.0725 | times:100 }}")
580
+ assert_template_result("-7.25", '{{ "-0.0725" | times:100 }}')
581
+ assert_template_result("7.25", '{{ "-0.0725" | times: -100 }}')
582
+ assert_template_result("4", "{{ price | times:2 }}", 'price' => NumberLikeThing.new(2))
575
583
  end
576
584
 
577
585
  def test_divided_by
578
- assert_template_result "4", "{{ 12 | divided_by:3 }}"
579
- assert_template_result "4", "{{ 14 | divided_by:3 }}"
586
+ assert_template_result("4", "{{ 12 | divided_by:3 }}")
587
+ assert_template_result("4", "{{ 14 | divided_by:3 }}")
580
588
 
581
- assert_template_result "5", "{{ 15 | divided_by:3 }}"
582
- assert_equal "Liquid error: divided by 0", Template.parse("{{ 5 | divided_by:0 }}").render
589
+ assert_template_result("5", "{{ 15 | divided_by:3 }}")
590
+ assert_equal("Liquid error: divided by 0", Template.parse("{{ 5 | divided_by:0 }}").render)
583
591
 
584
- assert_template_result "0.5", "{{ 2.0 | divided_by:4 }}"
592
+ assert_template_result("0.5", "{{ 2.0 | divided_by:4 }}")
585
593
  assert_raises(Liquid::ZeroDivisionError) do
586
- assert_template_result "4", "{{ 1 | modulo: 0 }}"
594
+ assert_template_result("4", "{{ 1 | modulo: 0 }}")
587
595
  end
588
596
 
589
- assert_template_result "5", "{{ price | divided_by:2 }}", 'price' => NumberLikeThing.new(10)
597
+ assert_template_result("5", "{{ price | divided_by:2 }}", 'price' => NumberLikeThing.new(10))
590
598
  end
591
599
 
592
600
  def test_modulo
593
- assert_template_result "1", "{{ 3 | modulo:2 }}"
601
+ assert_template_result("1", "{{ 3 | modulo:2 }}")
594
602
  assert_raises(Liquid::ZeroDivisionError) do
595
- assert_template_result "4", "{{ 1 | modulo: 0 }}"
603
+ assert_template_result("4", "{{ 1 | modulo: 0 }}")
596
604
  end
597
605
 
598
- assert_template_result "1", "{{ price | modulo:2 }}", 'price' => NumberLikeThing.new(3)
606
+ assert_template_result("1", "{{ price | modulo:2 }}", 'price' => NumberLikeThing.new(3))
599
607
  end
600
608
 
601
609
  def test_round
602
- assert_template_result "5", "{{ input | round }}", 'input' => 4.6
603
- assert_template_result "4", "{{ '4.3' | round }}"
604
- assert_template_result "4.56", "{{ input | round: 2 }}", 'input' => 4.5612
610
+ assert_template_result("5", "{{ input | round }}", 'input' => 4.6)
611
+ assert_template_result("4", "{{ '4.3' | round }}")
612
+ assert_template_result("4.56", "{{ input | round: 2 }}", 'input' => 4.5612)
605
613
  assert_raises(Liquid::FloatDomainError) do
606
- assert_template_result "4", "{{ 1.0 | divided_by: 0.0 | round }}"
614
+ assert_template_result("4", "{{ 1.0 | divided_by: 0.0 | round }}")
607
615
  end
608
616
 
609
- assert_template_result "5", "{{ price | round }}", 'price' => NumberLikeThing.new(4.6)
610
- assert_template_result "4", "{{ price | round }}", 'price' => NumberLikeThing.new(4.3)
617
+ assert_template_result("5", "{{ price | round }}", 'price' => NumberLikeThing.new(4.6))
618
+ assert_template_result("4", "{{ price | round }}", 'price' => NumberLikeThing.new(4.3))
611
619
  end
612
620
 
613
621
  def test_ceil
614
- assert_template_result "5", "{{ input | ceil }}", 'input' => 4.6
615
- assert_template_result "5", "{{ '4.3' | ceil }}"
622
+ assert_template_result("5", "{{ input | ceil }}", 'input' => 4.6)
623
+ assert_template_result("5", "{{ '4.3' | ceil }}")
616
624
  assert_raises(Liquid::FloatDomainError) do
617
- assert_template_result "4", "{{ 1.0 | divided_by: 0.0 | ceil }}"
625
+ assert_template_result("4", "{{ 1.0 | divided_by: 0.0 | ceil }}")
618
626
  end
619
627
 
620
- assert_template_result "5", "{{ price | ceil }}", 'price' => NumberLikeThing.new(4.6)
628
+ assert_template_result("5", "{{ price | ceil }}", 'price' => NumberLikeThing.new(4.6))
621
629
  end
622
630
 
623
631
  def test_floor
624
- assert_template_result "4", "{{ input | floor }}", 'input' => 4.6
625
- assert_template_result "4", "{{ '4.3' | floor }}"
632
+ assert_template_result("4", "{{ input | floor }}", 'input' => 4.6)
633
+ assert_template_result("4", "{{ '4.3' | floor }}")
626
634
  assert_raises(Liquid::FloatDomainError) do
627
- assert_template_result "4", "{{ 1.0 | divided_by: 0.0 | floor }}"
635
+ assert_template_result("4", "{{ 1.0 | divided_by: 0.0 | floor }}")
628
636
  end
629
637
 
630
- assert_template_result "5", "{{ price | floor }}", 'price' => NumberLikeThing.new(5.4)
638
+ assert_template_result("5", "{{ price | floor }}", 'price' => NumberLikeThing.new(5.4))
631
639
  end
632
640
 
633
641
  def test_at_most
634
- assert_template_result "4", "{{ 5 | at_most:4 }}"
635
- assert_template_result "5", "{{ 5 | at_most:5 }}"
636
- assert_template_result "5", "{{ 5 | at_most:6 }}"
642
+ assert_template_result("4", "{{ 5 | at_most:4 }}")
643
+ assert_template_result("5", "{{ 5 | at_most:5 }}")
644
+ assert_template_result("5", "{{ 5 | at_most:6 }}")
637
645
 
638
- assert_template_result "4.5", "{{ 4.5 | at_most:5 }}"
639
- assert_template_result "5", "{{ width | at_most:5 }}", 'width' => NumberLikeThing.new(6)
640
- assert_template_result "4", "{{ width | at_most:5 }}", 'width' => NumberLikeThing.new(4)
641
- assert_template_result "4", "{{ 5 | at_most: width }}", 'width' => NumberLikeThing.new(4)
646
+ assert_template_result("4.5", "{{ 4.5 | at_most:5 }}")
647
+ assert_template_result("5", "{{ width | at_most:5 }}", 'width' => NumberLikeThing.new(6))
648
+ assert_template_result("4", "{{ width | at_most:5 }}", 'width' => NumberLikeThing.new(4))
649
+ assert_template_result("4", "{{ 5 | at_most: width }}", 'width' => NumberLikeThing.new(4))
642
650
  end
643
651
 
644
652
  def test_at_least
645
- assert_template_result "5", "{{ 5 | at_least:4 }}"
646
- assert_template_result "5", "{{ 5 | at_least:5 }}"
647
- assert_template_result "6", "{{ 5 | at_least:6 }}"
653
+ assert_template_result("5", "{{ 5 | at_least:4 }}")
654
+ assert_template_result("5", "{{ 5 | at_least:5 }}")
655
+ assert_template_result("6", "{{ 5 | at_least:6 }}")
648
656
 
649
- assert_template_result "5", "{{ 4.5 | at_least:5 }}"
650
- assert_template_result "6", "{{ width | at_least:5 }}", 'width' => NumberLikeThing.new(6)
651
- assert_template_result "5", "{{ width | at_least:5 }}", 'width' => NumberLikeThing.new(4)
652
- assert_template_result "6", "{{ 5 | at_least: width }}", 'width' => NumberLikeThing.new(6)
657
+ assert_template_result("5", "{{ 4.5 | at_least:5 }}")
658
+ assert_template_result("6", "{{ width | at_least:5 }}", 'width' => NumberLikeThing.new(6))
659
+ assert_template_result("5", "{{ width | at_least:5 }}", 'width' => NumberLikeThing.new(4))
660
+ assert_template_result("6", "{{ 5 | at_least: width }}", 'width' => NumberLikeThing.new(6))
653
661
  end
654
662
 
655
663
  def test_append
@@ -659,9 +667,9 @@ class StandardFiltersTest < Minitest::Test
659
667
  end
660
668
 
661
669
  def test_concat
662
- assert_equal [1, 2, 3, 4], @filters.concat([1, 2], [3, 4])
663
- assert_equal [1, 2, 'a'], @filters.concat([1, 2], ['a'])
664
- assert_equal [1, 2, 10], @filters.concat([1, 2], [10])
670
+ assert_equal([1, 2, 3, 4], @filters.concat([1, 2], [3, 4]))
671
+ assert_equal([1, 2, 'a'], @filters.concat([1, 2], ['a']))
672
+ assert_equal([1, 2, 10], @filters.concat([1, 2], [10]))
665
673
 
666
674
  assert_raises(Liquid::ArgumentError, "concat filter requires an array argument") do
667
675
  @filters.concat([1, 2], 10)
@@ -675,12 +683,23 @@ class StandardFiltersTest < Minitest::Test
675
683
  end
676
684
 
677
685
  def test_default
678
- assert_equal "foo", @filters.default("foo", "bar")
679
- assert_equal "bar", @filters.default(nil, "bar")
680
- assert_equal "bar", @filters.default("", "bar")
681
- assert_equal "bar", @filters.default(false, "bar")
682
- assert_equal "bar", @filters.default([], "bar")
683
- assert_equal "bar", @filters.default({}, "bar")
686
+ assert_equal("foo", @filters.default("foo", "bar"))
687
+ assert_equal("bar", @filters.default(nil, "bar"))
688
+ assert_equal("bar", @filters.default("", "bar"))
689
+ assert_equal("bar", @filters.default(false, "bar"))
690
+ assert_equal("bar", @filters.default([], "bar"))
691
+ assert_equal("bar", @filters.default({}, "bar"))
692
+ assert_template_result('bar', "{{ false | default: 'bar' }}")
693
+ end
694
+
695
+ def test_default_handle_false
696
+ assert_equal("foo", @filters.default("foo", "bar", "allow_false" => true))
697
+ assert_equal("bar", @filters.default(nil, "bar", "allow_false" => true))
698
+ assert_equal("bar", @filters.default("", "bar", "allow_false" => true))
699
+ assert_equal(false, @filters.default(false, "bar", "allow_false" => true))
700
+ assert_equal("bar", @filters.default([], "bar", "allow_false" => true))
701
+ assert_equal("bar", @filters.default({}, "bar", "allow_false" => true))
702
+ assert_template_result('false', "{{ false | default: 'bar', allow_false: true }}")
684
703
  end
685
704
 
686
705
  def test_cannot_access_private_methods
@@ -697,16 +716,16 @@ class StandardFiltersTest < Minitest::Test
697
716
  { "handle" => "alpha", "ok" => true },
698
717
  { "handle" => "beta", "ok" => false },
699
718
  { "handle" => "gamma", "ok" => false },
700
- { "handle" => "delta", "ok" => true }
719
+ { "handle" => "delta", "ok" => true },
701
720
  ]
702
721
 
703
722
  expectation = [
704
723
  { "handle" => "alpha", "ok" => true },
705
- { "handle" => "delta", "ok" => true }
724
+ { "handle" => "delta", "ok" => true },
706
725
  ]
707
726
 
708
- assert_equal expectation, @filters.where(input, "ok", true)
709
- assert_equal expectation, @filters.where(input, "ok")
727
+ assert_equal(expectation, @filters.where(input, "ok", true))
728
+ assert_equal(expectation, @filters.where(input, "ok"))
710
729
  end
711
730
 
712
731
  def test_where_no_key_set
@@ -714,21 +733,21 @@ class StandardFiltersTest < Minitest::Test
714
733
  { "handle" => "alpha", "ok" => true },
715
734
  { "handle" => "beta" },
716
735
  { "handle" => "gamma" },
717
- { "handle" => "delta", "ok" => true }
736
+ { "handle" => "delta", "ok" => true },
718
737
  ]
719
738
 
720
739
  expectation = [
721
740
  { "handle" => "alpha", "ok" => true },
722
- { "handle" => "delta", "ok" => true }
741
+ { "handle" => "delta", "ok" => true },
723
742
  ]
724
743
 
725
- assert_equal expectation, @filters.where(input, "ok", true)
726
- assert_equal expectation, @filters.where(input, "ok")
744
+ assert_equal(expectation, @filters.where(input, "ok", true))
745
+ assert_equal(expectation, @filters.where(input, "ok"))
727
746
  end
728
747
 
729
748
  def test_where_non_array_map_input
730
- assert_equal [{ "a" => "ok" }], @filters.where({ "a" => "ok" }, "a", "ok")
731
- assert_equal [], @filters.where({ "a" => "not ok" }, "a", "ok")
749
+ assert_equal([{ "a" => "ok" }], @filters.where({ "a" => "ok" }, "a", "ok"))
750
+ assert_equal([], @filters.where({ "a" => "not ok" }, "a", "ok"))
732
751
  end
733
752
 
734
753
  def test_where_indexable_but_non_map_value
@@ -740,17 +759,60 @@ class StandardFiltersTest < Minitest::Test
740
759
  input = [
741
760
  { "message" => "Bonjour!", "language" => "French" },
742
761
  { "message" => "Hello!", "language" => "English" },
743
- { "message" => "Hallo!", "language" => "German" }
762
+ { "message" => "Hallo!", "language" => "German" },
744
763
  ]
745
764
 
746
- assert_equal [{ "message" => "Bonjour!", "language" => "French" }], @filters.where(input, "language", "French")
747
- assert_equal [{ "message" => "Hallo!", "language" => "German" }], @filters.where(input, "language", "German")
748
- assert_equal [{ "message" => "Hello!", "language" => "English" }], @filters.where(input, "language", "English")
765
+ assert_equal([{ "message" => "Bonjour!", "language" => "French" }], @filters.where(input, "language", "French"))
766
+ assert_equal([{ "message" => "Hallo!", "language" => "German" }], @filters.where(input, "language", "German"))
767
+ assert_equal([{ "message" => "Hello!", "language" => "English" }], @filters.where(input, "language", "English"))
749
768
  end
750
769
 
751
770
  def test_where_array_of_only_unindexable_values
752
- assert_nil @filters.where([nil], "ok", true)
753
- assert_nil @filters.where([nil], "ok")
771
+ assert_nil(@filters.where([nil], "ok", true))
772
+ assert_nil(@filters.where([nil], "ok"))
773
+ end
774
+
775
+ def test_all_filters_never_raise_non_liquid_exception
776
+ test_drop = TestDrop.new
777
+ test_drop.context = Context.new
778
+ test_enum = TestEnumerable.new
779
+ test_enum.context = Context.new
780
+ test_types = [
781
+ "foo",
782
+ 123,
783
+ 0,
784
+ 0.0,
785
+ -1234.003030303,
786
+ -99999999,
787
+ 1234.38383000383830003838300,
788
+ nil,
789
+ true,
790
+ false,
791
+ TestThing.new,
792
+ test_drop,
793
+ test_enum,
794
+ ["foo", "bar"],
795
+ { "foo" => "bar" },
796
+ { foo: "bar" },
797
+ [{ "foo" => "bar" }, { "foo" => 123 }, { "foo" => nil }, { "foo" => true }, { "foo" => ["foo", "bar"] }],
798
+ { 1 => "bar" },
799
+ ["foo", 123, nil, true, false, Drop, ["foo"], { foo: "bar" }],
800
+ ]
801
+ test_types.each do |first|
802
+ test_types.each do |other|
803
+ (@filters.methods - Object.methods).each do |method|
804
+ arg_count = @filters.method(method).arity
805
+ arg_count *= -1 if arg_count < 0
806
+ inputs = [first]
807
+ inputs << ([other] * (arg_count - 1)) if arg_count > 1
808
+ begin
809
+ @filters.send(method, *inputs)
810
+ rescue Liquid::ArgumentError, Liquid::ZeroDivisionError
811
+ nil
812
+ end
813
+ end
814
+ end
815
+ end
754
816
  end
755
817
 
756
818
  def test_where_no_target_value
@@ -758,16 +820,16 @@ class StandardFiltersTest < Minitest::Test
758
820
  { "foo" => false },
759
821
  { "foo" => true },
760
822
  { "foo" => "for sure" },
761
- { "bar" => true }
823
+ { "bar" => true },
762
824
  ]
763
825
 
764
- assert_equal [{ "foo" => true }, { "foo" => "for sure" }], @filters.where(input, "foo")
826
+ assert_equal([{ "foo" => true }, { "foo" => "for sure" }], @filters.where(input, "foo"))
765
827
  end
766
828
 
767
829
  private
768
830
 
769
831
  def with_timezone(tz)
770
- old_tz = ENV['TZ']
832
+ old_tz = ENV['TZ']
771
833
  ENV['TZ'] = tz
772
834
  yield
773
835
  ensure