liquid 4.0.3 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +33 -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 +164 -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 +16 -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 +63 -44
  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 +26 -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 +55 -71
  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 +608 -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 +339 -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 +2 -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 +19 -17
  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,158 @@ 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))
174
178
  end
175
179
 
176
180
  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)
181
+ assert_equal('test', @filters.strip_html("<div>test</div>"))
182
+ assert_equal('test', @filters.strip_html("<div id='test'>test</div>"))
183
+ assert_equal('', @filters.strip_html("<script type='text/javascript'>document.write('some stuff');</script>"))
184
+ assert_equal('', @filters.strip_html("<style type='text/css'>foo bar</style>"))
185
+ assert_equal('test', @filters.strip_html("<div\nclass='multiline'>test</div>"))
186
+ assert_equal('test', @filters.strip_html("<!-- foo bar \n test -->test"))
187
+ assert_equal('', @filters.strip_html(nil))
184
188
 
185
189
  # Quirk of the existing implementation
186
- assert_equal 'foo;', @filters.strip_html("<<<script </script>script>foo;</script>")
190
+ assert_equal('foo;', @filters.strip_html("<<<script </script>script>foo;</script>"))
187
191
  end
188
192
 
189
193
  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)
194
+ assert_equal('1 2 3 4', @filters.join([1, 2, 3, 4]))
195
+ assert_equal('1 - 2 - 3 - 4', @filters.join([1, 2, 3, 4], ' - '))
196
+ assert_equal('1121314', @filters.join([1, 2, 3, 4], 1))
193
197
  end
194
198
 
195
199
  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")
200
+ assert_equal([1, 2, 3, 4], @filters.sort([4, 3, 2, 1]))
201
+ assert_equal([{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }], @filters.sort([{ "a" => 4 }, { "a" => 3 }, { "a" => 1 }, { "a" => 2 }], "a"))
198
202
  end
199
203
 
200
204
  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")
205
+ assert_equal([1, 2, 3, 4, nil], @filters.sort([nil, 4, 3, 2, 1]))
206
+ assert_equal([{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }, {}], @filters.sort([{ "a" => 4 }, { "a" => 3 }, {}, { "a" => 1 }, { "a" => 2 }], "a"))
203
207
  end
204
208
 
205
209
  def test_sort_when_property_is_sometimes_missing_puts_nils_last
206
- input = [
210
+ input = [
207
211
  { "price" => 4, "handle" => "alpha" },
208
212
  { "handle" => "beta" },
209
213
  { "price" => 1, "handle" => "gamma" },
210
214
  { "handle" => "delta" },
211
- { "price" => 2, "handle" => "epsilon" }
215
+ { "price" => 2, "handle" => "epsilon" },
212
216
  ]
213
217
  expectation = [
214
218
  { "price" => 1, "handle" => "gamma" },
215
219
  { "price" => 2, "handle" => "epsilon" },
216
220
  { "price" => 4, "handle" => "alpha" },
217
221
  { "handle" => "delta" },
218
- { "handle" => "beta" }
222
+ { "handle" => "beta" },
219
223
  ]
220
- assert_equal expectation, @filters.sort(input, "price")
224
+ assert_equal(expectation, @filters.sort(input, "price"))
221
225
  end
222
226
 
223
227
  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")
228
+ assert_equal(["a", "B", "c", "D"], @filters.sort_natural(["c", "D", "a", "B"]))
229
+ assert_equal([{ "a" => "a" }, { "a" => "B" }, { "a" => "c" }, { "a" => "D" }], @filters.sort_natural([{ "a" => "D" }, { "a" => "c" }, { "a" => "a" }, { "a" => "B" }], "a"))
226
230
  end
227
231
 
228
232
  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")
233
+ assert_equal(["a", "B", "c", "D", nil], @filters.sort_natural([nil, "c", "D", "a", "B"]))
234
+ assert_equal([{ "a" => "a" }, { "a" => "B" }, { "a" => "c" }, { "a" => "D" }, {}], @filters.sort_natural([{ "a" => "D" }, { "a" => "c" }, {}, { "a" => "a" }, { "a" => "B" }], "a"))
231
235
  end
232
236
 
233
237
  def test_sort_natural_when_property_is_sometimes_missing_puts_nils_last
234
- input = [
238
+ input = [
235
239
  { "price" => "4", "handle" => "alpha" },
236
240
  { "handle" => "beta" },
237
241
  { "price" => "1", "handle" => "gamma" },
238
242
  { "handle" => "delta" },
239
- { "price" => 2, "handle" => "epsilon" }
243
+ { "price" => 2, "handle" => "epsilon" },
240
244
  ]
241
245
  expectation = [
242
246
  { "price" => "1", "handle" => "gamma" },
243
247
  { "price" => 2, "handle" => "epsilon" },
244
248
  { "price" => "4", "handle" => "alpha" },
245
249
  { "handle" => "delta" },
246
- { "handle" => "beta" }
250
+ { "handle" => "beta" },
247
251
  ]
248
- assert_equal expectation, @filters.sort_natural(input, "price")
252
+ assert_equal(expectation, @filters.sort_natural(input, "price"))
249
253
  end
250
254
 
251
255
  def test_sort_natural_case_check
@@ -256,7 +260,7 @@ class StandardFiltersTest < Minitest::Test
256
260
  { "fake" => "t" },
257
261
  { "key" => "a" },
258
262
  { "key" => "b" },
259
- { "key" => "c" }
263
+ { "key" => "c" },
260
264
  ]
261
265
  expectation = [
262
266
  { "key" => "a" },
@@ -265,168 +269,168 @@ class StandardFiltersTest < Minitest::Test
265
269
  { "key" => "X" },
266
270
  { "key" => "Y" },
267
271
  { "key" => "Z" },
268
- { "fake" => "t" }
272
+ { "fake" => "t" },
269
273
  ]
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"])
274
+ assert_equal(expectation, @filters.sort_natural(input, "key"))
275
+ assert_equal(["a", "b", "c", "X", "Y", "Z"], @filters.sort_natural(["X", "Y", "Z", "a", "b", "c"]))
272
276
  end
273
277
 
274
278
  def test_sort_empty_array
275
- assert_equal [], @filters.sort([], "a")
279
+ assert_equal([], @filters.sort([], "a"))
276
280
  end
277
281
 
278
282
  def test_sort_invalid_property
279
283
  foo = [
280
284
  [1],
281
285
  [2],
282
- [3]
286
+ [3],
283
287
  ]
284
288
 
285
- assert_raises Liquid::ArgumentError do
289
+ assert_raises(Liquid::ArgumentError) do
286
290
  @filters.sort(foo, "bar")
287
291
  end
288
292
  end
289
293
 
290
294
  def test_sort_natural_empty_array
291
- assert_equal [], @filters.sort_natural([], "a")
295
+ assert_equal([], @filters.sort_natural([], "a"))
292
296
  end
293
297
 
294
298
  def test_sort_natural_invalid_property
295
299
  foo = [
296
300
  [1],
297
301
  [2],
298
- [3]
302
+ [3],
299
303
  ]
300
304
 
301
- assert_raises Liquid::ArgumentError do
305
+ assert_raises(Liquid::ArgumentError) do
302
306
  @filters.sort_natural(foo, "bar")
303
307
  end
304
308
  end
305
309
 
306
310
  def test_legacy_sort_hash
307
- assert_equal [{ a: 1, b: 2 }], @filters.sort({ a: 1, b: 2 })
311
+ assert_equal([{ a: 1, b: 2 }], @filters.sort(a: 1, b: 2))
308
312
  end
309
313
 
310
314
  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")
315
+ assert_equal([2, 10], @filters.sort([10, 2]))
316
+ assert_equal([{ "a" => 2 }, { "a" => 10 }], @filters.sort([{ "a" => 10 }, { "a" => 2 }], "a"))
317
+ assert_equal(["10", "2"], @filters.sort(["10", "2"]))
318
+ assert_equal([{ "a" => "10" }, { "a" => "2" }], @filters.sort([{ "a" => "10" }, { "a" => "2" }], "a"))
315
319
  end
316
320
 
317
321
  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")
322
+ assert_equal(["foo"], @filters.uniq("foo"))
323
+ assert_equal([1, 3, 2, 4], @filters.uniq([1, 1, 3, 2, 3, 1, 4, 3, 2, 1]))
324
+ assert_equal([{ "a" => 1 }, { "a" => 3 }, { "a" => 2 }], @filters.uniq([{ "a" => 1 }, { "a" => 3 }, { "a" => 1 }, { "a" => 2 }], "a"))
321
325
  testdrop = TestDrop.new
322
- assert_equal [testdrop], @filters.uniq([testdrop, TestDrop.new], 'test')
326
+ assert_equal([testdrop], @filters.uniq([testdrop, TestDrop.new], 'test'))
323
327
  end
324
328
 
325
329
  def test_uniq_empty_array
326
- assert_equal [], @filters.uniq([], "a")
330
+ assert_equal([], @filters.uniq([], "a"))
327
331
  end
328
332
 
329
333
  def test_uniq_invalid_property
330
334
  foo = [
331
335
  [1],
332
336
  [2],
333
- [3]
337
+ [3],
334
338
  ]
335
339
 
336
- assert_raises Liquid::ArgumentError do
340
+ assert_raises(Liquid::ArgumentError) do
337
341
  @filters.uniq(foo, "bar")
338
342
  end
339
343
  end
340
344
 
341
345
  def test_compact_empty_array
342
- assert_equal [], @filters.compact([], "a")
346
+ assert_equal([], @filters.compact([], "a"))
343
347
  end
344
348
 
345
349
  def test_compact_invalid_property
346
350
  foo = [
347
351
  [1],
348
352
  [2],
349
- [3]
353
+ [3],
350
354
  ]
351
355
 
352
- assert_raises Liquid::ArgumentError do
356
+ assert_raises(Liquid::ArgumentError) do
353
357
  @filters.compact(foo, "bar")
354
358
  end
355
359
  end
356
360
 
357
361
  def test_reverse
358
- assert_equal [4, 3, 2, 1], @filters.reverse([1, 2, 3, 4])
362
+ assert_equal([4, 3, 2, 1], @filters.reverse([1, 2, 3, 4]))
359
363
  end
360
364
 
361
365
  def test_legacy_reverse_hash
362
- assert_equal [{ a: 1, b: 2 }], @filters.reverse(a: 1, b: 2)
366
+ assert_equal([{ a: 1, b: 2 }], @filters.reverse(a: 1, b: 2))
363
367
  end
364
368
 
365
369
  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' } }]
370
+ assert_equal([1, 2, 3, 4], @filters.map([{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }], 'a'))
371
+ assert_template_result('abc', "{{ ary | map:'foo' | map:'bar' }}",
372
+ 'ary' => [{ 'foo' => { 'bar' => 'a' } }, { 'foo' => { 'bar' => 'b' } }, { 'foo' => { 'bar' => 'c' } }])
369
373
  end
370
374
 
371
375
  def test_map_doesnt_call_arbitrary_stuff
372
- assert_template_result "", '{{ "foo" | map: "__id__" }}'
373
- assert_template_result "", '{{ "foo" | map: "inspect" }}'
376
+ assert_template_result("", '{{ "foo" | map: "__id__" }}')
377
+ assert_template_result("", '{{ "foo" | map: "inspect" }}')
374
378
  end
375
379
 
376
380
  def test_map_calls_to_liquid
377
381
  t = TestThing.new
378
- assert_template_result "woot: 1", '{{ foo | map: "whatever" }}', "foo" => [t]
382
+ assert_template_result("woot: 1", '{{ foo | map: "whatever" }}', "foo" => [t])
379
383
  end
380
384
 
381
385
  def test_map_on_hashes
382
- assert_template_result "4217", '{{ thing | map: "foo" | map: "bar" }}',
383
- "thing" => { "foo" => [ { "bar" => 42 }, { "bar" => 17 } ] }
386
+ assert_template_result("4217", '{{ thing | map: "foo" | map: "bar" }}',
387
+ "thing" => { "foo" => [{ "bar" => 42 }, { "bar" => 17 }] })
384
388
  end
385
389
 
386
390
  def test_legacy_map_on_hashes_with_dynamic_key
387
391
  template = "{% assign key = 'foo' %}{{ thing | map: key | map: 'bar' }}"
388
- hash = { "foo" => { "bar" => 42 } }
389
- assert_template_result "42", template, "thing" => hash
392
+ hash = { "foo" => { "bar" => 42 } }
393
+ assert_template_result("42", template, "thing" => hash)
390
394
  end
391
395
 
392
396
  def test_sort_calls_to_liquid
393
397
  t = TestThing.new
394
398
  Liquid::Template.parse('{{ foo | sort: "whatever" }}').render("foo" => [t])
395
- assert t.foo > 0
399
+ assert(t.foo > 0)
396
400
  end
397
401
 
398
402
  def test_map_over_proc
399
- drop = TestDrop.new
400
- p = proc{ drop }
403
+ drop = TestDrop.new
404
+ p = proc { drop }
401
405
  templ = '{{ procs | map: "test" }}'
402
- assert_template_result "testfoo", templ, "procs" => [p]
406
+ assert_template_result("testfoo", templ, "procs" => [p])
403
407
  end
404
408
 
405
409
  def test_map_over_drops_returning_procs
406
410
  drops = [
407
411
  {
408
- "proc" => ->{ "foo" },
412
+ "proc" => -> { "foo" },
409
413
  },
410
414
  {
411
- "proc" => ->{ "bar" },
415
+ "proc" => -> { "bar" },
412
416
  },
413
417
  ]
414
418
  templ = '{{ drops | map: "proc" }}'
415
- assert_template_result "foobar", templ, "drops" => drops
419
+ assert_template_result("foobar", templ, "drops" => drops)
416
420
  end
417
421
 
418
422
  def test_map_works_on_enumerables
419
- assert_template_result "123", '{{ foo | map: "foo" }}', "foo" => TestEnumerable.new
423
+ assert_template_result("123", '{{ foo | map: "foo" }}', "foo" => TestEnumerable.new)
420
424
  end
421
425
 
422
426
  def test_map_returns_empty_on_2d_input_array
423
427
  foo = [
424
428
  [1],
425
429
  [2],
426
- [3]
430
+ [3],
427
431
  ]
428
432
 
429
- assert_raises Liquid::ArgumentError do
433
+ assert_raises(Liquid::ArgumentError) do
430
434
  @filters.map(foo, "bar")
431
435
  end
432
436
  end
@@ -435,221 +439,221 @@ class StandardFiltersTest < Minitest::Test
435
439
  foo = [
436
440
  [1],
437
441
  [2],
438
- [3]
442
+ [3],
439
443
  ]
440
- assert_raises Liquid::ArgumentError do
444
+ assert_raises(Liquid::ArgumentError) do
441
445
  @filters.map(foo, nil)
442
446
  end
443
447
  end
444
448
 
445
449
  def test_sort_works_on_enumerables
446
- assert_template_result "213", '{{ foo | sort: "bar" | map: "foo" }}', "foo" => TestEnumerable.new
450
+ assert_template_result("213", '{{ foo | sort: "bar" | map: "foo" }}', "foo" => TestEnumerable.new)
447
451
  end
448
452
 
449
453
  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]
454
+ assert_template_result('foobar', '{{ foo | first }}', 'foo' => [ThingWithToLiquid.new])
455
+ assert_template_result('foobar', '{{ foo | last }}', 'foo' => [ThingWithToLiquid.new])
452
456
  end
453
457
 
454
458
  def test_truncate_calls_to_liquid
455
- assert_template_result "wo...", '{{ foo | truncate: 5 }}', "foo" => TestThing.new
459
+ assert_template_result("wo...", '{{ foo | truncate: 5 }}', "foo" => TestThing.new)
456
460
  end
457
461
 
458
462
  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")
463
+ assert_equal('May', @filters.date(Time.parse("2006-05-05 10:00:00"), "%B"))
464
+ assert_equal('June', @filters.date(Time.parse("2006-06-05 10:00:00"), "%B"))
465
+ assert_equal('July', @filters.date(Time.parse("2006-07-05 10:00:00"), "%B"))
462
466
 
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")
467
+ assert_equal('May', @filters.date("2006-05-05 10:00:00", "%B"))
468
+ assert_equal('June', @filters.date("2006-06-05 10:00:00", "%B"))
469
+ assert_equal('July', @filters.date("2006-07-05 10:00:00", "%B"))
466
470
 
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)
471
+ assert_equal('2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", ""))
472
+ assert_equal('2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", ""))
473
+ assert_equal('2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", ""))
474
+ assert_equal('2006-07-05 10:00:00', @filters.date("2006-07-05 10:00:00", nil))
471
475
 
472
- assert_equal '07/05/2006', @filters.date("2006-07-05 10:00:00", "%m/%d/%Y")
476
+ assert_equal('07/05/2006', @filters.date("2006-07-05 10:00:00", "%m/%d/%Y"))
473
477
 
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')
478
+ assert_equal("07/16/2004", @filters.date("Fri Jul 16 01:00:00 2004", "%m/%d/%Y"))
479
+ assert_equal(Date.today.year.to_s, @filters.date('now', '%Y'))
480
+ assert_equal(Date.today.year.to_s, @filters.date('today', '%Y'))
481
+ assert_equal(Date.today.year.to_s, @filters.date('Today', '%Y'))
478
482
 
479
- assert_nil @filters.date(nil, "%B")
483
+ assert_nil(@filters.date(nil, "%B"))
480
484
 
481
- assert_equal '', @filters.date('', "%B")
485
+ assert_equal('', @filters.date('', "%B"))
482
486
 
483
487
  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")
488
+ assert_equal("07/05/2006", @filters.date(1152098955, "%m/%d/%Y"))
489
+ assert_equal("07/05/2006", @filters.date("1152098955", "%m/%d/%Y"))
486
490
  end
487
491
  end
488
492
 
489
493
  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([])
494
+ assert_equal(1, @filters.first([1, 2, 3]))
495
+ assert_equal(3, @filters.last([1, 2, 3]))
496
+ assert_nil(@filters.first([]))
497
+ assert_nil(@filters.last([]))
494
498
  end
495
499
 
496
500
  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 }}"
501
+ assert_equal('2 2 2 2', @filters.replace('1 1 1 1', '1', 2))
502
+ assert_equal('2 2 2 2', @filters.replace('1 1 1 1', 1, 2))
503
+ assert_equal('2 1 1 1', @filters.replace_first('1 1 1 1', '1', 2))
504
+ assert_equal('2 1 1 1', @filters.replace_first('1 1 1 1', 1, 2))
505
+ assert_template_result('2 1 1 1', "{{ '1 1 1 1' | replace_first: '1', 2 }}")
502
506
  end
503
507
 
504
508
  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 ' }}"
509
+ assert_equal(' ', @filters.remove("a a a a", 'a'))
510
+ assert_equal(' ', @filters.remove("1 1 1 1", 1))
511
+ assert_equal('a a a', @filters.remove_first("a a a a", 'a '))
512
+ assert_equal(' 1 1 1', @filters.remove_first("1 1 1 1", 1))
513
+ assert_template_result('a a a', "{{ 'a a a a' | remove_first: 'a ' }}")
510
514
  end
511
515
 
512
516
  def test_pipes_in_string_arguments
513
- assert_template_result 'foobar', "{{ 'foo|bar' | remove: '|' }}"
517
+ assert_template_result('foobar', "{{ 'foo|bar' | remove: '|' }}")
514
518
  end
515
519
 
516
520
  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"
521
+ assert_template_result('ab c', "{{ source | strip }}", 'source' => " ab c ")
522
+ assert_template_result('ab c', "{{ source | strip }}", 'source' => " \tab c \n \t")
519
523
  end
520
524
 
521
525
  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"
526
+ assert_template_result('ab c ', "{{ source | lstrip }}", 'source' => " ab c ")
527
+ assert_template_result("ab c \n \t", "{{ source | lstrip }}", 'source' => " \tab c \n \t")
524
528
  end
525
529
 
526
530
  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"
531
+ assert_template_result(" ab c", "{{ source | rstrip }}", 'source' => " ab c ")
532
+ assert_template_result(" \tab c", "{{ source | rstrip }}", 'source' => " \tab c \n \t")
529
533
  end
530
534
 
531
535
  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"
536
+ assert_template_result('abc', "{{ source | strip_newlines }}", 'source' => "a\nb\nc")
537
+ assert_template_result('abc', "{{ source | strip_newlines }}", 'source' => "a\r\nb\nc")
534
538
  end
535
539
 
536
540
  def test_newlines_to_br
537
- assert_template_result "a<br />\nb<br />\nc", "{{ source | newline_to_br }}", 'source' => "a\nb\nc"
541
+ assert_template_result("a<br />\nb<br />\nc", "{{ source | newline_to_br }}", 'source' => "a\nb\nc")
538
542
  end
539
543
 
540
544
  def test_plus
541
- assert_template_result "2", "{{ 1 | plus:1 }}"
542
- assert_template_result "2.0", "{{ '1' | plus:'1.0' }}"
545
+ assert_template_result("2", "{{ 1 | plus:1 }}")
546
+ assert_template_result("2.0", "{{ '1' | plus:'1.0' }}")
543
547
 
544
- assert_template_result "5", "{{ price | plus:'2' }}", 'price' => NumberLikeThing.new(3)
548
+ assert_template_result("5", "{{ price | plus:'2' }}", 'price' => NumberLikeThing.new(3))
545
549
  end
546
550
 
547
551
  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' }}"
552
+ assert_template_result("4", "{{ input | minus:operand }}", 'input' => 5, 'operand' => 1)
553
+ assert_template_result("2.3", "{{ '4.3' | minus:'2' }}")
550
554
 
551
- assert_template_result "5", "{{ price | minus:'2' }}", 'price' => NumberLikeThing.new(7)
555
+ assert_template_result("5", "{{ price | minus:'2' }}", 'price' => NumberLikeThing.new(7))
552
556
  end
553
557
 
554
558
  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 }}"
559
+ assert_template_result("17", "{{ 17 | abs }}")
560
+ assert_template_result("17", "{{ -17 | abs }}")
561
+ assert_template_result("17", "{{ '17' | abs }}")
562
+ assert_template_result("17", "{{ '-17' | abs }}")
563
+ assert_template_result("0", "{{ 0 | abs }}")
564
+ assert_template_result("0", "{{ '0' | abs }}")
565
+ assert_template_result("17.42", "{{ 17.42 | abs }}")
566
+ assert_template_result("17.42", "{{ -17.42 | abs }}")
567
+ assert_template_result("17.42", "{{ '17.42' | abs }}")
568
+ assert_template_result("17.42", "{{ '-17.42' | abs }}")
565
569
  end
566
570
 
567
571
  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)
572
+ assert_template_result("12", "{{ 3 | times:4 }}")
573
+ assert_template_result("0", "{{ 'foo' | times:4 }}")
574
+ assert_template_result("6", "{{ '2.1' | times:3 | replace: '.','-' | plus:0}}")
575
+ assert_template_result("7.25", "{{ 0.0725 | times:100 }}")
576
+ assert_template_result("-7.25", '{{ "-0.0725" | times:100 }}')
577
+ assert_template_result("7.25", '{{ "-0.0725" | times: -100 }}')
578
+ assert_template_result("4", "{{ price | times:2 }}", 'price' => NumberLikeThing.new(2))
575
579
  end
576
580
 
577
581
  def test_divided_by
578
- assert_template_result "4", "{{ 12 | divided_by:3 }}"
579
- assert_template_result "4", "{{ 14 | divided_by:3 }}"
582
+ assert_template_result("4", "{{ 12 | divided_by:3 }}")
583
+ assert_template_result("4", "{{ 14 | divided_by:3 }}")
580
584
 
581
- assert_template_result "5", "{{ 15 | divided_by:3 }}"
582
- assert_equal "Liquid error: divided by 0", Template.parse("{{ 5 | divided_by:0 }}").render
585
+ assert_template_result("5", "{{ 15 | divided_by:3 }}")
586
+ assert_equal("Liquid error: divided by 0", Template.parse("{{ 5 | divided_by:0 }}").render)
583
587
 
584
- assert_template_result "0.5", "{{ 2.0 | divided_by:4 }}"
588
+ assert_template_result("0.5", "{{ 2.0 | divided_by:4 }}")
585
589
  assert_raises(Liquid::ZeroDivisionError) do
586
- assert_template_result "4", "{{ 1 | modulo: 0 }}"
590
+ assert_template_result("4", "{{ 1 | modulo: 0 }}")
587
591
  end
588
592
 
589
- assert_template_result "5", "{{ price | divided_by:2 }}", 'price' => NumberLikeThing.new(10)
593
+ assert_template_result("5", "{{ price | divided_by:2 }}", 'price' => NumberLikeThing.new(10))
590
594
  end
591
595
 
592
596
  def test_modulo
593
- assert_template_result "1", "{{ 3 | modulo:2 }}"
597
+ assert_template_result("1", "{{ 3 | modulo:2 }}")
594
598
  assert_raises(Liquid::ZeroDivisionError) do
595
- assert_template_result "4", "{{ 1 | modulo: 0 }}"
599
+ assert_template_result("4", "{{ 1 | modulo: 0 }}")
596
600
  end
597
601
 
598
- assert_template_result "1", "{{ price | modulo:2 }}", 'price' => NumberLikeThing.new(3)
602
+ assert_template_result("1", "{{ price | modulo:2 }}", 'price' => NumberLikeThing.new(3))
599
603
  end
600
604
 
601
605
  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
606
+ assert_template_result("5", "{{ input | round }}", 'input' => 4.6)
607
+ assert_template_result("4", "{{ '4.3' | round }}")
608
+ assert_template_result("4.56", "{{ input | round: 2 }}", 'input' => 4.5612)
605
609
  assert_raises(Liquid::FloatDomainError) do
606
- assert_template_result "4", "{{ 1.0 | divided_by: 0.0 | round }}"
610
+ assert_template_result("4", "{{ 1.0 | divided_by: 0.0 | round }}")
607
611
  end
608
612
 
609
- assert_template_result "5", "{{ price | round }}", 'price' => NumberLikeThing.new(4.6)
610
- assert_template_result "4", "{{ price | round }}", 'price' => NumberLikeThing.new(4.3)
613
+ assert_template_result("5", "{{ price | round }}", 'price' => NumberLikeThing.new(4.6))
614
+ assert_template_result("4", "{{ price | round }}", 'price' => NumberLikeThing.new(4.3))
611
615
  end
612
616
 
613
617
  def test_ceil
614
- assert_template_result "5", "{{ input | ceil }}", 'input' => 4.6
615
- assert_template_result "5", "{{ '4.3' | ceil }}"
618
+ assert_template_result("5", "{{ input | ceil }}", 'input' => 4.6)
619
+ assert_template_result("5", "{{ '4.3' | ceil }}")
616
620
  assert_raises(Liquid::FloatDomainError) do
617
- assert_template_result "4", "{{ 1.0 | divided_by: 0.0 | ceil }}"
621
+ assert_template_result("4", "{{ 1.0 | divided_by: 0.0 | ceil }}")
618
622
  end
619
623
 
620
- assert_template_result "5", "{{ price | ceil }}", 'price' => NumberLikeThing.new(4.6)
624
+ assert_template_result("5", "{{ price | ceil }}", 'price' => NumberLikeThing.new(4.6))
621
625
  end
622
626
 
623
627
  def test_floor
624
- assert_template_result "4", "{{ input | floor }}", 'input' => 4.6
625
- assert_template_result "4", "{{ '4.3' | floor }}"
628
+ assert_template_result("4", "{{ input | floor }}", 'input' => 4.6)
629
+ assert_template_result("4", "{{ '4.3' | floor }}")
626
630
  assert_raises(Liquid::FloatDomainError) do
627
- assert_template_result "4", "{{ 1.0 | divided_by: 0.0 | floor }}"
631
+ assert_template_result("4", "{{ 1.0 | divided_by: 0.0 | floor }}")
628
632
  end
629
633
 
630
- assert_template_result "5", "{{ price | floor }}", 'price' => NumberLikeThing.new(5.4)
634
+ assert_template_result("5", "{{ price | floor }}", 'price' => NumberLikeThing.new(5.4))
631
635
  end
632
636
 
633
637
  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 }}"
638
+ assert_template_result("4", "{{ 5 | at_most:4 }}")
639
+ assert_template_result("5", "{{ 5 | at_most:5 }}")
640
+ assert_template_result("5", "{{ 5 | at_most:6 }}")
637
641
 
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)
642
+ assert_template_result("4.5", "{{ 4.5 | at_most:5 }}")
643
+ assert_template_result("5", "{{ width | at_most:5 }}", 'width' => NumberLikeThing.new(6))
644
+ assert_template_result("4", "{{ width | at_most:5 }}", 'width' => NumberLikeThing.new(4))
645
+ assert_template_result("4", "{{ 5 | at_most: width }}", 'width' => NumberLikeThing.new(4))
642
646
  end
643
647
 
644
648
  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 }}"
649
+ assert_template_result("5", "{{ 5 | at_least:4 }}")
650
+ assert_template_result("5", "{{ 5 | at_least:5 }}")
651
+ assert_template_result("6", "{{ 5 | at_least:6 }}")
648
652
 
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)
653
+ assert_template_result("5", "{{ 4.5 | at_least:5 }}")
654
+ assert_template_result("6", "{{ width | at_least:5 }}", 'width' => NumberLikeThing.new(6))
655
+ assert_template_result("5", "{{ width | at_least:5 }}", 'width' => NumberLikeThing.new(4))
656
+ assert_template_result("6", "{{ 5 | at_least: width }}", 'width' => NumberLikeThing.new(6))
653
657
  end
654
658
 
655
659
  def test_append
@@ -659,9 +663,9 @@ class StandardFiltersTest < Minitest::Test
659
663
  end
660
664
 
661
665
  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])
666
+ assert_equal([1, 2, 3, 4], @filters.concat([1, 2], [3, 4]))
667
+ assert_equal([1, 2, 'a'], @filters.concat([1, 2], ['a']))
668
+ assert_equal([1, 2, 10], @filters.concat([1, 2], [10]))
665
669
 
666
670
  assert_raises(Liquid::ArgumentError, "concat filter requires an array argument") do
667
671
  @filters.concat([1, 2], 10)
@@ -675,12 +679,23 @@ class StandardFiltersTest < Minitest::Test
675
679
  end
676
680
 
677
681
  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")
682
+ assert_equal("foo", @filters.default("foo", "bar"))
683
+ assert_equal("bar", @filters.default(nil, "bar"))
684
+ assert_equal("bar", @filters.default("", "bar"))
685
+ assert_equal("bar", @filters.default(false, "bar"))
686
+ assert_equal("bar", @filters.default([], "bar"))
687
+ assert_equal("bar", @filters.default({}, "bar"))
688
+ assert_template_result('bar', "{{ false | default: 'bar' }}")
689
+ end
690
+
691
+ def test_default_handle_false
692
+ assert_equal("foo", @filters.default("foo", "bar", "allow_false" => true))
693
+ assert_equal("bar", @filters.default(nil, "bar", "allow_false" => true))
694
+ assert_equal("bar", @filters.default("", "bar", "allow_false" => true))
695
+ assert_equal(false, @filters.default(false, "bar", "allow_false" => true))
696
+ assert_equal("bar", @filters.default([], "bar", "allow_false" => true))
697
+ assert_equal("bar", @filters.default({}, "bar", "allow_false" => true))
698
+ assert_template_result('false', "{{ false | default: 'bar', allow_false: true }}")
684
699
  end
685
700
 
686
701
  def test_cannot_access_private_methods
@@ -697,16 +712,16 @@ class StandardFiltersTest < Minitest::Test
697
712
  { "handle" => "alpha", "ok" => true },
698
713
  { "handle" => "beta", "ok" => false },
699
714
  { "handle" => "gamma", "ok" => false },
700
- { "handle" => "delta", "ok" => true }
715
+ { "handle" => "delta", "ok" => true },
701
716
  ]
702
717
 
703
718
  expectation = [
704
719
  { "handle" => "alpha", "ok" => true },
705
- { "handle" => "delta", "ok" => true }
720
+ { "handle" => "delta", "ok" => true },
706
721
  ]
707
722
 
708
- assert_equal expectation, @filters.where(input, "ok", true)
709
- assert_equal expectation, @filters.where(input, "ok")
723
+ assert_equal(expectation, @filters.where(input, "ok", true))
724
+ assert_equal(expectation, @filters.where(input, "ok"))
710
725
  end
711
726
 
712
727
  def test_where_no_key_set
@@ -714,21 +729,21 @@ class StandardFiltersTest < Minitest::Test
714
729
  { "handle" => "alpha", "ok" => true },
715
730
  { "handle" => "beta" },
716
731
  { "handle" => "gamma" },
717
- { "handle" => "delta", "ok" => true }
732
+ { "handle" => "delta", "ok" => true },
718
733
  ]
719
734
 
720
735
  expectation = [
721
736
  { "handle" => "alpha", "ok" => true },
722
- { "handle" => "delta", "ok" => true }
737
+ { "handle" => "delta", "ok" => true },
723
738
  ]
724
739
 
725
- assert_equal expectation, @filters.where(input, "ok", true)
726
- assert_equal expectation, @filters.where(input, "ok")
740
+ assert_equal(expectation, @filters.where(input, "ok", true))
741
+ assert_equal(expectation, @filters.where(input, "ok"))
727
742
  end
728
743
 
729
744
  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")
745
+ assert_equal([{ "a" => "ok" }], @filters.where({ "a" => "ok" }, "a", "ok"))
746
+ assert_equal([], @filters.where({ "a" => "not ok" }, "a", "ok"))
732
747
  end
733
748
 
734
749
  def test_where_indexable_but_non_map_value
@@ -740,17 +755,60 @@ class StandardFiltersTest < Minitest::Test
740
755
  input = [
741
756
  { "message" => "Bonjour!", "language" => "French" },
742
757
  { "message" => "Hello!", "language" => "English" },
743
- { "message" => "Hallo!", "language" => "German" }
758
+ { "message" => "Hallo!", "language" => "German" },
744
759
  ]
745
760
 
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")
761
+ assert_equal([{ "message" => "Bonjour!", "language" => "French" }], @filters.where(input, "language", "French"))
762
+ assert_equal([{ "message" => "Hallo!", "language" => "German" }], @filters.where(input, "language", "German"))
763
+ assert_equal([{ "message" => "Hello!", "language" => "English" }], @filters.where(input, "language", "English"))
749
764
  end
750
765
 
751
766
  def test_where_array_of_only_unindexable_values
752
- assert_nil @filters.where([nil], "ok", true)
753
- assert_nil @filters.where([nil], "ok")
767
+ assert_nil(@filters.where([nil], "ok", true))
768
+ assert_nil(@filters.where([nil], "ok"))
769
+ end
770
+
771
+ def test_all_filters_never_raise_non_liquid_exception
772
+ test_drop = TestDrop.new
773
+ test_drop.context = Context.new
774
+ test_enum = TestEnumerable.new
775
+ test_enum.context = Context.new
776
+ test_types = [
777
+ "foo",
778
+ 123,
779
+ 0,
780
+ 0.0,
781
+ -1234.003030303,
782
+ -99999999,
783
+ 1234.38383000383830003838300,
784
+ nil,
785
+ true,
786
+ false,
787
+ TestThing.new,
788
+ test_drop,
789
+ test_enum,
790
+ ["foo", "bar"],
791
+ { "foo" => "bar" },
792
+ { foo: "bar" },
793
+ [{ "foo" => "bar" }, { "foo" => 123 }, { "foo" => nil }, { "foo" => true }, { "foo" => ["foo", "bar"] }],
794
+ { 1 => "bar" },
795
+ ["foo", 123, nil, true, false, Drop, ["foo"], { foo: "bar" }],
796
+ ]
797
+ test_types.each do |first|
798
+ test_types.each do |other|
799
+ (@filters.methods - Object.methods).each do |method|
800
+ arg_count = @filters.method(method).arity
801
+ arg_count *= -1 if arg_count < 0
802
+ inputs = [first]
803
+ inputs << ([other] * (arg_count - 1)) if arg_count > 1
804
+ begin
805
+ @filters.send(method, *inputs)
806
+ rescue Liquid::ArgumentError, Liquid::ZeroDivisionError
807
+ nil
808
+ end
809
+ end
810
+ end
811
+ end
754
812
  end
755
813
 
756
814
  def test_where_no_target_value
@@ -758,16 +816,16 @@ class StandardFiltersTest < Minitest::Test
758
816
  { "foo" => false },
759
817
  { "foo" => true },
760
818
  { "foo" => "for sure" },
761
- { "bar" => true }
819
+ { "bar" => true },
762
820
  ]
763
821
 
764
- assert_equal [{ "foo" => true }, { "foo" => "for sure" }], @filters.where(input, "foo")
822
+ assert_equal([{ "foo" => true }, { "foo" => "for sure" }], @filters.where(input, "foo"))
765
823
  end
766
824
 
767
825
  private
768
826
 
769
827
  def with_timezone(tz)
770
- old_tz = ENV['TZ']
828
+ old_tz = ENV['TZ']
771
829
  ENV['TZ'] = tz
772
830
  yield
773
831
  ensure