liquid 5.0.1 → 5.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class FilterKwargTest < Minitest::Test
6
+ module KwargFilter
7
+ def html_tag(_tag, attributes)
8
+ attributes
9
+ .map { |key, value| "#{key}='#{value}'" }
10
+ .join(' ')
11
+ end
12
+ end
13
+
14
+ include Liquid
15
+
16
+ def test_can_parse_data_kwargs
17
+ with_global_filter(KwargFilter) do
18
+ assert_equal(
19
+ "data-src='src' data-widths='100, 200'",
20
+ Template.parse("{{ 'img' | html_tag: data-src: 'src', data-widths: '100, 200' }}").render(nil, nil)
21
+ )
22
+ end
23
+ end
24
+ end
@@ -3,6 +3,27 @@
3
3
  require 'test_helper'
4
4
 
5
5
  class ProfilerTest < Minitest::Test
6
+ class TestDrop < Liquid::Drop
7
+ def initialize(value)
8
+ super()
9
+ @value = value
10
+ end
11
+
12
+ def to_s
13
+ artificial_execution_time
14
+
15
+ @value
16
+ end
17
+
18
+ private
19
+
20
+ # Monotonic clock precision fluctuate based on the operating system
21
+ # By introducing a small sleep we ensure ourselves to register a non zero unit of time
22
+ def artificial_execution_time
23
+ sleep(Process.clock_getres(Process::CLOCK_MONOTONIC))
24
+ end
25
+ end
26
+
6
27
  include Liquid
7
28
 
8
29
  class ProfilingFileSystem
@@ -198,16 +219,22 @@ class ProfilerTest < Minitest::Test
198
219
 
199
220
  def test_profiling_supports_self_time
200
221
  t = Template.parse("{% for item in collection %} {{ item }} {% endfor %}", profile: true)
201
- t.render!("collection" => ["one", "two"])
202
- leaf = t.profiler[0].children[0]
222
+ collection = [
223
+ TestDrop.new("one"),
224
+ TestDrop.new("two"),
225
+ ]
226
+ output = t.render!("collection" => collection)
227
+ assert_equal(" one two ", output)
203
228
 
204
- assert_operator(leaf.self_time, :>, 0)
229
+ leaf = t.profiler[0].children[0]
230
+ assert_operator(leaf.self_time, :>, 0.0)
205
231
  end
206
232
 
207
233
  def test_profiling_supports_total_time
208
- t = Template.parse("{% if true %} {% increment test %} {{ test }} {% endif %}", profile: true)
209
- t.render!
234
+ t = Template.parse("{% if true %} {{ test }} {% endif %}", profile: true)
235
+ output = t.render!("test" => TestDrop.new("one"))
236
+ assert_equal(" one ", output)
210
237
 
211
- assert_operator(t.profiler[0].total_time, :>, 0)
238
+ assert_operator(t.profiler[0].total_time, :>, 0.0)
212
239
  end
213
240
  end
@@ -3,10 +3,6 @@
3
3
 
4
4
  require 'test_helper'
5
5
 
6
- class Filters
7
- include Liquid::StandardFilters
8
- end
9
-
10
6
  class TestThing
11
7
  attr_reader :foo
12
8
 
@@ -29,8 +25,24 @@ class TestThing
29
25
  end
30
26
 
31
27
  class TestDrop < Liquid::Drop
32
- def test
33
- "testfoo"
28
+ def initialize(value:)
29
+ @value = value
30
+ end
31
+
32
+ attr_reader :value
33
+
34
+ def registers
35
+ @context.registers
36
+ end
37
+ end
38
+
39
+ class TestModel
40
+ def initialize(value:)
41
+ @value = value
42
+ end
43
+
44
+ def to_liquid
45
+ TestDrop.new(value: @value)
34
46
  end
35
47
  end
36
48
 
@@ -53,10 +65,13 @@ class NumberLikeThing < Liquid::Drop
53
65
  end
54
66
 
55
67
  class StandardFiltersTest < Minitest::Test
68
+ Filters = Class.new(Liquid::StrainerTemplate)
69
+ Filters.add_filter(Liquid::StandardFilters)
70
+
56
71
  include Liquid
57
72
 
58
73
  def setup
59
- @filters = Filters.new
74
+ @filters = Filters.new(Context.new)
60
75
  end
61
76
 
62
77
  def test_size
@@ -145,6 +160,40 @@ class StandardFiltersTest < Minitest::Test
145
160
  assert_equal('&lt;strong&gt;Hulk&lt;/strong&gt;', @filters.escape_once('&lt;strong&gt;Hulk</strong>'))
146
161
  end
147
162
 
163
+ def test_base64_encode
164
+ assert_equal('b25lIHR3byB0aHJlZQ==', @filters.base64_encode('one two three'))
165
+ assert_equal('', @filters.base64_encode(nil))
166
+ end
167
+
168
+ def test_base64_decode
169
+ assert_equal('one two three', @filters.base64_decode('b25lIHR3byB0aHJlZQ=='))
170
+
171
+ exception = assert_raises(Liquid::ArgumentError) do
172
+ @filters.base64_decode("invalidbase64")
173
+ end
174
+
175
+ assert_equal('Liquid error: invalid base64 provided to base64_decode', exception.message)
176
+ end
177
+
178
+ def test_base64_url_safe_encode
179
+ assert_equal(
180
+ 'YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXogQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVogMTIzNDU2Nzg5MCAhQCMkJV4mKigpLT1fKy8_Ljo7W117fVx8',
181
+ @filters.base64_url_safe_encode('abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890 !@#$%^&*()-=_+/?.:;[]{}\|')
182
+ )
183
+ assert_equal('', @filters.base64_url_safe_encode(nil))
184
+ end
185
+
186
+ def test_base64_url_safe_decode
187
+ assert_equal(
188
+ 'abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890 !@#$%^&*()-=_+/?.:;[]{}\|',
189
+ @filters.base64_url_safe_decode('YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXogQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVogMTIzNDU2Nzg5MCAhQCMkJV4mKigpLT1fKy8_Ljo7W117fVx8')
190
+ )
191
+ exception = assert_raises(Liquid::ArgumentError) do
192
+ @filters.base64_url_safe_decode("invalidbase64")
193
+ end
194
+ assert_equal('Liquid error: invalid base64 provided to base64_url_safe_decode', exception.message)
195
+ end
196
+
148
197
  def test_url_encode
149
198
  assert_equal('foo%2B1%40example.com', @filters.url_encode('foo+1@example.com'))
150
199
  assert_equal('1', @filters.url_encode(1))
@@ -178,6 +227,10 @@ class StandardFiltersTest < Minitest::Test
178
227
  assert_equal('one two three...', @filters.truncatewords("one two\tthree\nfour", 3))
179
228
  assert_equal('one two...', @filters.truncatewords("one two three four", 2))
180
229
  assert_equal('one...', @filters.truncatewords("one two three four", 0))
230
+ exception = assert_raises(Liquid::ArgumentError) do
231
+ @filters.truncatewords("one two three four", 1 << 31)
232
+ end
233
+ assert_equal("Liquid error: integer #{1 << 31} too big for truncatewords", exception.message)
181
234
  end
182
235
 
183
236
  def test_strip_html
@@ -221,8 +274,8 @@ class StandardFiltersTest < Minitest::Test
221
274
  { "price" => 1, "handle" => "gamma" },
222
275
  { "price" => 2, "handle" => "epsilon" },
223
276
  { "price" => 4, "handle" => "alpha" },
224
- { "handle" => "delta" },
225
277
  { "handle" => "beta" },
278
+ { "handle" => "delta" },
226
279
  ]
227
280
  assert_equal(expectation, @filters.sort(input, "price"))
228
281
  end
@@ -325,8 +378,9 @@ class StandardFiltersTest < Minitest::Test
325
378
  assert_equal(["foo"], @filters.uniq("foo"))
326
379
  assert_equal([1, 3, 2, 4], @filters.uniq([1, 1, 3, 2, 3, 1, 4, 3, 2, 1]))
327
380
  assert_equal([{ "a" => 1 }, { "a" => 3 }, { "a" => 2 }], @filters.uniq([{ "a" => 1 }, { "a" => 3 }, { "a" => 1 }, { "a" => 2 }], "a"))
328
- testdrop = TestDrop.new
329
- assert_equal([testdrop], @filters.uniq([testdrop, TestDrop.new], 'test'))
381
+ test_drop = TestDrop.new(value: "test")
382
+ test_drop_alternate = TestDrop.new(value: "test")
383
+ assert_equal([test_drop], @filters.uniq([test_drop, test_drop_alternate], 'value'))
330
384
  end
331
385
 
332
386
  def test_uniq_empty_array
@@ -385,6 +439,16 @@ class StandardFiltersTest < Minitest::Test
385
439
  assert_template_result("woot: 1", '{{ foo | map: "whatever" }}', "foo" => [t])
386
440
  end
387
441
 
442
+ def test_map_calls_context=
443
+ model = TestModel.new(value: "test")
444
+
445
+ template = Template.parse('{{ foo | map: "registers" }}')
446
+ template.registers[:test] = 1234
447
+ template.assigns['foo'] = [model]
448
+
449
+ assert_template_result("{:test=>1234}", template.render!)
450
+ end
451
+
388
452
  def test_map_on_hashes
389
453
  assert_template_result("4217", '{{ thing | map: "foo" | map: "bar" }}',
390
454
  "thing" => { "foo" => [{ "bar" => 42 }, { "bar" => 17 }] })
@@ -403,9 +467,9 @@ class StandardFiltersTest < Minitest::Test
403
467
  end
404
468
 
405
469
  def test_map_over_proc
406
- drop = TestDrop.new
470
+ drop = TestDrop.new(value: "testfoo")
407
471
  p = proc { drop }
408
- templ = '{{ procs | map: "test" }}'
472
+ templ = '{{ procs | map: "value" }}'
409
473
  assert_template_result("testfoo", templ, "procs" => [p])
410
474
  end
411
475
 
@@ -501,19 +565,31 @@ class StandardFiltersTest < Minitest::Test
501
565
  end
502
566
 
503
567
  def test_replace
504
- assert_equal('2 2 2 2', @filters.replace('1 1 1 1', '1', 2))
568
+ assert_equal('b b b b', @filters.replace('a a a a', 'a', 'b'))
505
569
  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))
570
+ assert_equal('1 1 1 1', @filters.replace('1 1 1 1', 2, 3))
571
+ assert_template_result('2 2 2 2', "{{ '1 1 1 1' | replace: '1', 2 }}")
572
+
573
+ assert_equal('b a a a', @filters.replace_first('a a a a', 'a', 'b'))
507
574
  assert_equal('2 1 1 1', @filters.replace_first('1 1 1 1', 1, 2))
575
+ assert_equal('1 1 1 1', @filters.replace_first('1 1 1 1', 2, 3))
508
576
  assert_template_result('2 1 1 1', "{{ '1 1 1 1' | replace_first: '1', 2 }}")
577
+
578
+ assert_equal('a a a b', @filters.replace_last('a a a a', 'a', 'b'))
579
+ assert_equal('1 1 1 2', @filters.replace_last('1 1 1 1', 1, 2))
580
+ assert_equal('1 1 1 1', @filters.replace_last('1 1 1 1', 2, 3))
581
+ assert_template_result('1 1 1 2', "{{ '1 1 1 1' | replace_last: '1', 2 }}")
509
582
  end
510
583
 
511
584
  def test_remove
512
585
  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 ' }}")
586
+ assert_template_result(' ', "{{ '1 1 1 1' | remove: 1 }}")
587
+
588
+ assert_equal('b a a', @filters.remove_first("a b a a", 'a '))
589
+ assert_template_result(' 1 1 1', "{{ '1 1 1 1' | remove_first: 1 }}")
590
+
591
+ assert_equal('a a b', @filters.remove_last("a a b a", ' a'))
592
+ assert_template_result('1 1 1 ', "{{ '1 1 1 1' | remove_last: 1 }}")
517
593
  end
518
594
 
519
595
  def test_pipes_in_string_arguments
@@ -690,6 +766,8 @@ class StandardFiltersTest < Minitest::Test
690
766
  assert_equal("bar", @filters.default([], "bar"))
691
767
  assert_equal("bar", @filters.default({}, "bar"))
692
768
  assert_template_result('bar', "{{ false | default: 'bar' }}")
769
+ assert_template_result('bar', "{{ drop | default: 'bar' }}", 'drop' => BooleanDrop.new(false))
770
+ assert_template_result('Yay', "{{ drop | default: 'bar' }}", 'drop' => BooleanDrop.new(true))
693
771
  end
694
772
 
695
773
  def test_default_handle_false
@@ -700,6 +778,8 @@ class StandardFiltersTest < Minitest::Test
700
778
  assert_equal("bar", @filters.default([], "bar", "allow_false" => true))
701
779
  assert_equal("bar", @filters.default({}, "bar", "allow_false" => true))
702
780
  assert_template_result('false', "{{ false | default: 'bar', allow_false: true }}")
781
+ assert_template_result('Nay', "{{ drop | default: 'bar', allow_false: true }}", 'drop' => BooleanDrop.new(false))
782
+ assert_template_result('Yay', "{{ drop | default: 'bar', allow_false: true }}", 'drop' => BooleanDrop.new(true))
703
783
  end
704
784
 
705
785
  def test_cannot_access_private_methods
@@ -728,6 +808,18 @@ class StandardFiltersTest < Minitest::Test
728
808
  assert_equal(expectation, @filters.where(input, "ok"))
729
809
  end
730
810
 
811
+ def test_where_string_keys
812
+ input = [
813
+ "alpha", "beta", "gamma", "delta"
814
+ ]
815
+
816
+ expectation = [
817
+ "beta",
818
+ ]
819
+
820
+ assert_equal(expectation, @filters.where(input, "be"))
821
+ end
822
+
731
823
  def test_where_no_key_set
732
824
  input = [
733
825
  { "handle" => "alpha", "ok" => true },
@@ -773,7 +865,7 @@ class StandardFiltersTest < Minitest::Test
773
865
  end
774
866
 
775
867
  def test_all_filters_never_raise_non_liquid_exception
776
- test_drop = TestDrop.new
868
+ test_drop = TestDrop.new(value: "test")
777
869
  test_drop.context = Context.new
778
870
  test_enum = TestEnumerable.new
779
871
  test_enum.context = Context.new
@@ -798,19 +890,14 @@ class StandardFiltersTest < Minitest::Test
798
890
  { 1 => "bar" },
799
891
  ["foo", 123, nil, true, false, Drop, ["foo"], { foo: "bar" }],
800
892
  ]
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
893
+ StandardFilters.public_instance_methods(false).each do |method|
894
+ arg_count = @filters.method(method).arity
895
+ arg_count *= -1 if arg_count < 0
896
+
897
+ test_types.repeated_permutation(arg_count) do |args|
898
+ @filters.send(method, *args)
899
+ rescue Liquid::Error
900
+ nil
814
901
  end
815
902
  end
816
903
  end
@@ -323,4 +323,18 @@ class TemplateTest < Minitest::Test
323
323
  result = t.render('x' => 1, 'y' => 5)
324
324
  assert_equal('12345', result)
325
325
  end
326
+
327
+ def test_source_string_subclass
328
+ string_subclass = Class.new(String) do
329
+ # E.g. ActiveSupport::SafeBuffer does this, so don't just rely on to_s to return a String
330
+ def to_s
331
+ self
332
+ end
333
+ end
334
+ source = string_subclass.new("{% assign x = 2 -%} x= {{- x }}")
335
+ assert_instance_of(string_subclass, source)
336
+ output = Template.parse(source).render!
337
+ assert_equal("x=2", output)
338
+ assert_instance_of(String, output)
339
+ end
326
340
  end
@@ -15,6 +15,33 @@ class VariableTest < Minitest::Test
15
15
  assert_template_result('foobar', '{{ foo }}', 'foo' => ThingWithToLiquid.new)
16
16
  end
17
17
 
18
+ def test_variable_lookup_calls_to_liquid_value
19
+ assert_template_result('1', '{{ foo }}', 'foo' => IntegerDrop.new('1'))
20
+ assert_template_result('2', '{{ list[foo] }}', 'foo' => IntegerDrop.new('1'), 'list' => [1, 2, 3])
21
+ assert_template_result('one', '{{ list[foo] }}', 'foo' => IntegerDrop.new('1'), 'list' => { 1 => 'one' })
22
+ assert_template_result('Yay', '{{ foo }}', 'foo' => BooleanDrop.new(true))
23
+ assert_template_result('YAY', '{{ foo | upcase }}', 'foo' => BooleanDrop.new(true))
24
+ end
25
+
26
+ def test_if_tag_calls_to_liquid_value
27
+ assert_template_result('one', '{% if foo == 1 %}one{% endif %}', 'foo' => IntegerDrop.new('1'))
28
+ assert_template_result('one', '{% if 0 < foo %}one{% endif %}', 'foo' => IntegerDrop.new('1'))
29
+ assert_template_result('one', '{% if foo > 0 %}one{% endif %}', 'foo' => IntegerDrop.new('1'))
30
+ assert_template_result('true', '{% if foo == true %}true{% endif %}', 'foo' => BooleanDrop.new(true))
31
+ assert_template_result('true', '{% if foo %}true{% endif %}', 'foo' => BooleanDrop.new(true))
32
+
33
+ assert_template_result('', '{% if foo %}true{% endif %}', 'foo' => BooleanDrop.new(false))
34
+ assert_template_result('', '{% if foo == true %}True{% endif %}', 'foo' => BooleanDrop.new(false))
35
+ end
36
+
37
+ def test_unless_tag_calls_to_liquid_value
38
+ assert_template_result('', '{% unless foo %}true{% endunless %}', 'foo' => BooleanDrop.new(true))
39
+ end
40
+
41
+ def test_case_tag_calls_to_liquid_value
42
+ assert_template_result('One', '{% case foo %}{% when 1 %}One{% endcase %}', 'foo' => IntegerDrop.new('1'))
43
+ end
44
+
18
45
  def test_simple_with_whitespaces
19
46
  template = Template.parse(%( {{ test }} ))
20
47
  assert_equal(' worked ', template.render!('test' => 'worked'))
@@ -104,4 +131,8 @@ class VariableTest < Minitest::Test
104
131
  def test_dynamic_find_var
105
132
  assert_template_result('bar', '{{ [key] }}', 'key' => 'foo', 'foo' => 'bar')
106
133
  end
134
+
135
+ def test_raw_value_variable
136
+ assert_template_result('bar', '{{ [key] }}', 'key' => 'foo', 'foo' => 'bar')
137
+ end
107
138
  end
data/test/test_helper.rb CHANGED
@@ -72,21 +72,21 @@ module Minitest
72
72
  end
73
73
 
74
74
  def with_global_filter(*globals)
75
- original_global_filters = Liquid::StrainerFactory.instance_variable_get(:@global_filters)
76
- Liquid::StrainerFactory.instance_variable_set(:@global_filters, [])
77
- globals.each do |global|
78
- Liquid::StrainerFactory.add_global_filter(global)
79
- end
80
-
81
- Liquid::StrainerFactory.send(:strainer_class_cache).clear
75
+ original_global_cache = Liquid::StrainerFactory::GlobalCache
76
+ Liquid::StrainerFactory.send(:remove_const, :GlobalCache)
77
+ Liquid::StrainerFactory.const_set(:GlobalCache, Class.new(Liquid::StrainerTemplate))
82
78
 
83
79
  globals.each do |global|
84
80
  Liquid::Template.register_filter(global)
85
81
  end
86
- yield
87
- ensure
88
82
  Liquid::StrainerFactory.send(:strainer_class_cache).clear
89
- Liquid::StrainerFactory.instance_variable_set(:@global_filters, original_global_filters)
83
+ begin
84
+ yield
85
+ ensure
86
+ Liquid::StrainerFactory.send(:remove_const, :GlobalCache)
87
+ Liquid::StrainerFactory.const_set(:GlobalCache, original_global_cache)
88
+ Liquid::StrainerFactory.send(:strainer_class_cache).clear
89
+ end
90
90
  end
91
91
 
92
92
  def with_error_mode(mode)
@@ -119,6 +119,44 @@ class ThingWithToLiquid
119
119
  end
120
120
  end
121
121
 
122
+ class IntegerDrop < Liquid::Drop
123
+ def initialize(value)
124
+ super()
125
+ @value = value.to_i
126
+ end
127
+
128
+ def ==(other)
129
+ @value == other
130
+ end
131
+
132
+ def to_s
133
+ @value.to_s
134
+ end
135
+
136
+ def to_liquid_value
137
+ @value
138
+ end
139
+ end
140
+
141
+ class BooleanDrop < Liquid::Drop
142
+ def initialize(value)
143
+ super()
144
+ @value = value
145
+ end
146
+
147
+ def ==(other)
148
+ @value == other
149
+ end
150
+
151
+ def to_liquid_value
152
+ @value
153
+ end
154
+
155
+ def to_s
156
+ @value ? "Yay" : "Nay"
157
+ end
158
+ end
159
+
122
160
  class ErrorDrop < Liquid::Drop
123
161
  def standard_error
124
162
  raise Liquid::StandardError, 'standard error'
@@ -10,8 +10,8 @@ class ConditionUnitTest < Minitest::Test
10
10
  end
11
11
 
12
12
  def test_basic_condition
13
- assert_equal(false, Condition.new(1, '==', 2).evaluate)
14
- assert_equal(true, Condition.new(1, '==', 1).evaluate)
13
+ assert_equal(false, Condition.new(1, '==', 2).evaluate(Context.new))
14
+ assert_equal(true, Condition.new(1, '==', 1).evaluate(Context.new))
15
15
  end
16
16
 
17
17
  def test_default_operators_evalute_true
@@ -67,11 +67,11 @@ class ConditionUnitTest < Minitest::Test
67
67
  end
68
68
 
69
69
  def test_hash_compare_backwards_compatibility
70
- assert_nil(Condition.new({}, '>', 2).evaluate)
71
- assert_nil(Condition.new(2, '>', {}).evaluate)
72
- assert_equal(false, Condition.new({}, '==', 2).evaluate)
73
- assert_equal(true, Condition.new({ 'a' => 1 }, '==', 'a' => 1).evaluate)
74
- assert_equal(true, Condition.new({ 'a' => 2 }, 'contains', 'a').evaluate)
70
+ assert_nil(Condition.new({}, '>', 2).evaluate(Context.new))
71
+ assert_nil(Condition.new(2, '>', {}).evaluate(Context.new))
72
+ assert_equal(false, Condition.new({}, '==', 2).evaluate(Context.new))
73
+ assert_equal(true, Condition.new({ 'a' => 1 }, '==', 'a' => 1).evaluate(Context.new))
74
+ assert_equal(true, Condition.new({ 'a' => 2 }, 'contains', 'a').evaluate(Context.new))
75
75
  end
76
76
 
77
77
  def test_contains_works_on_arrays
@@ -106,30 +106,29 @@ class ConditionUnitTest < Minitest::Test
106
106
 
107
107
  def test_or_condition
108
108
  condition = Condition.new(1, '==', 2)
109
-
110
- assert_equal(false, condition.evaluate)
109
+ assert_equal(false, condition.evaluate(Context.new))
111
110
 
112
111
  condition.or(Condition.new(2, '==', 1))
113
112
 
114
- assert_equal(false, condition.evaluate)
113
+ assert_equal(false, condition.evaluate(Context.new))
115
114
 
116
115
  condition.or(Condition.new(1, '==', 1))
117
116
 
118
- assert_equal(true, condition.evaluate)
117
+ assert_equal(true, condition.evaluate(Context.new))
119
118
  end
120
119
 
121
120
  def test_and_condition
122
121
  condition = Condition.new(1, '==', 1)
123
122
 
124
- assert_equal(true, condition.evaluate)
123
+ assert_equal(true, condition.evaluate(Context.new))
125
124
 
126
125
  condition.and(Condition.new(2, '==', 2))
127
126
 
128
- assert_equal(true, condition.evaluate)
127
+ assert_equal(true, condition.evaluate(Context.new))
129
128
 
130
129
  condition.and(Condition.new(2, '==', 1))
131
130
 
132
- assert_equal(false, condition.evaluate)
131
+ assert_equal(false, condition.evaluate(Context.new))
133
132
  end
134
133
 
135
134
  def test_should_allow_custom_proc_operator
@@ -148,6 +147,20 @@ class ConditionUnitTest < Minitest::Test
148
147
  assert_evaluates_true(VariableLookup.new("one"), '==', VariableLookup.new("another"))
149
148
  end
150
149
 
150
+ def test_default_context_is_deprecated
151
+ if Gem::Version.new(Liquid::VERSION) >= Gem::Version.new('6.0.0')
152
+ flunk("Condition#evaluate without a context argument is to be removed")
153
+ end
154
+
155
+ _out, err = capture_io do
156
+ assert_equal(true, Condition.new(1, '==', 1).evaluate)
157
+ end
158
+
159
+ expected = "DEPRECATION WARNING: Condition#evaluate without a context argument is deprecated" \
160
+ " and will be removed from Liquid 6.0.0."
161
+ assert_includes(err.lines.map(&:strip), expected)
162
+ end
163
+
151
164
  private
152
165
 
153
166
  def assert_evaluates_true(left, op, right)
@@ -159,6 +159,13 @@ class ParseTreeVisitorTest < Minitest::Test
159
159
  )
160
160
  end
161
161
 
162
+ def test_for_range
163
+ assert_equal(
164
+ ["test"],
165
+ visit(%({% for x in (1..test) %}{% endfor %}))
166
+ )
167
+ end
168
+
162
169
  def test_tablerow_in
163
170
  assert_equal(
164
171
  ["test"],
@@ -52,7 +52,8 @@ class StrainerFactoryUnitTest < Minitest::Test
52
52
  /\ALiquid error: wrong number of arguments \((1 for 0|given 1, expected 0)\)\z/,
53
53
  exception.message
54
54
  )
55
- assert_equal(exception.backtrace[0].split(':')[0], __FILE__)
55
+ source = AccessScopeFilters.instance_method(:public_filter).source_location
56
+ assert_equal(source.map(&:to_s), exception.backtrace[0].split(':')[0..1])
56
57
  end
57
58
 
58
59
  def test_strainer_only_invokes_public_filter_methods
@@ -57,8 +57,8 @@ class StrainerTemplateUnitTest < Minitest::Test
57
57
  end
58
58
 
59
59
  def test_add_filter_does_not_raise_when_module_overrides_previously_registered_method
60
- strainer = Context.new.strainer
61
60
  with_global_filter do
61
+ strainer = Context.new.strainer
62
62
  strainer.class.add_filter(PublicMethodOverrideFilter)
63
63
  assert(strainer.class.send(:filter_methods).include?('public_filter'))
64
64
  end