liquid 4.0.0.rc3 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +93 -2
  3. data/README.md +8 -0
  4. data/lib/liquid.rb +18 -5
  5. data/lib/liquid/block.rb +47 -20
  6. data/lib/liquid/block_body.rb +190 -76
  7. data/lib/liquid/condition.rb +69 -29
  8. data/lib/liquid/context.rb +122 -76
  9. data/lib/liquid/document.rb +47 -9
  10. data/lib/liquid/drop.rb +4 -2
  11. data/lib/liquid/errors.rb +20 -25
  12. data/lib/liquid/expression.rb +30 -31
  13. data/lib/liquid/extensions.rb +8 -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 +35 -26
  19. data/lib/liquid/locales/en.yml +4 -2
  20. data/lib/liquid/parse_context.rb +17 -4
  21. data/lib/liquid/parse_tree_visitor.rb +42 -0
  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 +171 -57
  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 +32 -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 +41 -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 +35 -16
  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 +79 -47
  48. data/lib/liquid/tags/if.rb +53 -30
  49. data/lib/liquid/tags/ifchanged.rb +11 -10
  50. data/lib/liquid/tags/include.rb +42 -44
  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 +32 -20
  55. data/lib/liquid/tags/unless.rb +15 -15
  56. data/lib/liquid/template.rb +60 -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 +6 -4
  61. data/lib/liquid/variable.rb +55 -38
  62. data/lib/liquid/variable_lookup.rb +14 -6
  63. data/lib/liquid/version.rb +3 -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 +58 -0
  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 +90 -60
  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 +24 -8
  77. data/test/integration/{render_profiling_test.rb → profiler_test.rb} +84 -25
  78. data/test/integration/security_test.rb +41 -18
  79. data/test/integration/standard_filter_test.rb +523 -205
  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 +109 -53
  86. data/test/integration/tags/if_else_tag_test.rb +5 -3
  87. data/test/integration/tags/include_tag_test.rb +83 -52
  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 +128 -121
  97. data/test/integration/trim_mode_test.rb +82 -44
  98. data/test/integration/variable_test.rb +46 -31
  99. data/test/test_helper.rb +75 -23
  100. data/test/unit/block_unit_test.rb +19 -24
  101. data/test/unit/condition_unit_test.rb +82 -72
  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 +12 -10
  105. data/test/unit/parse_tree_visitor_test.rb +247 -0
  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 +83 -50
  121. data/lib/liquid/strainer.rb +0 -65
  122. data/test/unit/context_unit_test.rb +0 -483
  123. data/test/unit/strainer_unit_test.rb +0 -136
@@ -1,65 +0,0 @@
1
- require 'set'
2
-
3
- module Liquid
4
- # Strainer is the parent class for the filters system.
5
- # New filters are mixed into the strainer class which is then instantiated for each liquid template render run.
6
- #
7
- # The Strainer only allows method calls defined in filters given to it via Strainer.global_filter,
8
- # Context#add_filters or Template.register_filter
9
- class Strainer #:nodoc:
10
- @@global_strainer = Class.new(Strainer) do
11
- @filter_methods = Set.new
12
- end
13
- @@strainer_class_cache = Hash.new do |hash, filters|
14
- hash[filters] = Class.new(@@global_strainer) do
15
- @filter_methods = @@global_strainer.filter_methods.dup
16
- filters.each { |f| add_filter(f) }
17
- end
18
- end
19
-
20
- def initialize(context)
21
- @context = context
22
- end
23
-
24
- class << self
25
- attr_reader :filter_methods
26
- end
27
-
28
- def self.add_filter(filter)
29
- raise ArgumentError, "Expected module but got: #{filter.class}" unless filter.is_a?(Module)
30
- unless self.class.include?(filter)
31
- invokable_non_public_methods = (filter.private_instance_methods + filter.protected_instance_methods).select { |m| invokable?(m) }
32
- if invokable_non_public_methods.any?
33
- raise MethodOverrideError, "Filter overrides registered public methods as non public: #{invokable_non_public_methods.join(', ')}"
34
- else
35
- send(:include, filter)
36
- @filter_methods.merge(filter.public_instance_methods.map(&:to_s))
37
- end
38
- end
39
- end
40
-
41
- def self.global_filter(filter)
42
- @@global_strainer.add_filter(filter)
43
- end
44
-
45
- def self.invokable?(method)
46
- @filter_methods.include?(method.to_s)
47
- end
48
-
49
- def self.create(context, filters = [])
50
- @@strainer_class_cache[filters].new(context)
51
- end
52
-
53
- def invoke(method, *args)
54
- if self.class.invokable?(method)
55
- send(method, *args)
56
- elsif @context && @context.strict_filters
57
- raise Liquid::UndefinedFilter, "undefined filter #{method}"
58
- else
59
- args.first
60
- end
61
- rescue ::ArgumentError => e
62
- raise Liquid::ArgumentError, e.message, e.backtrace
63
- end
64
- end
65
- end
@@ -1,483 +0,0 @@
1
- require 'test_helper'
2
-
3
- class HundredCentes
4
- def to_liquid
5
- 100
6
- end
7
- end
8
-
9
- class CentsDrop < Liquid::Drop
10
- def amount
11
- HundredCentes.new
12
- end
13
-
14
- def non_zero?
15
- true
16
- end
17
- end
18
-
19
- class ContextSensitiveDrop < Liquid::Drop
20
- def test
21
- @context['test']
22
- end
23
- end
24
-
25
- class Category < Liquid::Drop
26
- attr_accessor :name
27
-
28
- def initialize(name)
29
- @name = name
30
- end
31
-
32
- def to_liquid
33
- CategoryDrop.new(self)
34
- end
35
- end
36
-
37
- class CategoryDrop
38
- attr_accessor :category, :context
39
- def initialize(category)
40
- @category = category
41
- end
42
- end
43
-
44
- class CounterDrop < Liquid::Drop
45
- def count
46
- @count ||= 0
47
- @count += 1
48
- end
49
- end
50
-
51
- class ArrayLike
52
- def fetch(index)
53
- end
54
-
55
- def [](index)
56
- @counts ||= []
57
- @counts[index] ||= 0
58
- @counts[index] += 1
59
- end
60
-
61
- def to_liquid
62
- self
63
- end
64
- end
65
-
66
- class ContextUnitTest < Minitest::Test
67
- include Liquid
68
-
69
- def setup
70
- @context = Liquid::Context.new
71
- end
72
-
73
- def teardown
74
- Spy.teardown
75
- end
76
-
77
- def test_variables
78
- @context['string'] = 'string'
79
- assert_equal 'string', @context['string']
80
-
81
- @context['num'] = 5
82
- assert_equal 5, @context['num']
83
-
84
- @context['time'] = Time.parse('2006-06-06 12:00:00')
85
- assert_equal Time.parse('2006-06-06 12:00:00'), @context['time']
86
-
87
- @context['date'] = Date.today
88
- assert_equal Date.today, @context['date']
89
-
90
- now = DateTime.now
91
- @context['datetime'] = now
92
- assert_equal now, @context['datetime']
93
-
94
- @context['bool'] = true
95
- assert_equal true, @context['bool']
96
-
97
- @context['bool'] = false
98
- assert_equal false, @context['bool']
99
-
100
- @context['nil'] = nil
101
- assert_equal nil, @context['nil']
102
- assert_equal nil, @context['nil']
103
- end
104
-
105
- def test_variables_not_existing
106
- assert_equal nil, @context['does_not_exist']
107
- end
108
-
109
- def test_scoping
110
- @context.push
111
- @context.pop
112
-
113
- assert_raises(Liquid::ContextError) do
114
- @context.pop
115
- end
116
-
117
- assert_raises(Liquid::ContextError) do
118
- @context.push
119
- @context.pop
120
- @context.pop
121
- end
122
- end
123
-
124
- def test_length_query
125
- @context['numbers'] = [1, 2, 3, 4]
126
-
127
- assert_equal 4, @context['numbers.size']
128
-
129
- @context['numbers'] = { 1 => 1, 2 => 2, 3 => 3, 4 => 4 }
130
-
131
- assert_equal 4, @context['numbers.size']
132
-
133
- @context['numbers'] = { 1 => 1, 2 => 2, 3 => 3, 4 => 4, 'size' => 1000 }
134
-
135
- assert_equal 1000, @context['numbers.size']
136
- end
137
-
138
- def test_hyphenated_variable
139
- @context['oh-my'] = 'godz'
140
- assert_equal 'godz', @context['oh-my']
141
- end
142
-
143
- def test_add_filter
144
- filter = Module.new do
145
- def hi(output)
146
- output + ' hi!'
147
- end
148
- end
149
-
150
- context = Context.new
151
- context.add_filters(filter)
152
- assert_equal 'hi? hi!', context.invoke(:hi, 'hi?')
153
-
154
- context = Context.new
155
- assert_equal 'hi?', context.invoke(:hi, 'hi?')
156
-
157
- context.add_filters(filter)
158
- assert_equal 'hi? hi!', context.invoke(:hi, 'hi?')
159
- end
160
-
161
- def test_only_intended_filters_make_it_there
162
- filter = Module.new do
163
- def hi(output)
164
- output + ' hi!'
165
- end
166
- end
167
-
168
- context = Context.new
169
- assert_equal "Wookie", context.invoke("hi", "Wookie")
170
-
171
- context.add_filters(filter)
172
- assert_equal "Wookie hi!", context.invoke("hi", "Wookie")
173
- end
174
-
175
- def test_add_item_in_outer_scope
176
- @context['test'] = 'test'
177
- @context.push
178
- assert_equal 'test', @context['test']
179
- @context.pop
180
- assert_equal 'test', @context['test']
181
- end
182
-
183
- def test_add_item_in_inner_scope
184
- @context.push
185
- @context['test'] = 'test'
186
- assert_equal 'test', @context['test']
187
- @context.pop
188
- assert_equal nil, @context['test']
189
- end
190
-
191
- def test_hierachical_data
192
- @context['hash'] = { "name" => 'tobi' }
193
- assert_equal 'tobi', @context['hash.name']
194
- assert_equal 'tobi', @context['hash["name"]']
195
- end
196
-
197
- def test_keywords
198
- assert_equal true, @context['true']
199
- assert_equal false, @context['false']
200
- end
201
-
202
- def test_digits
203
- assert_equal 100, @context['100']
204
- assert_equal 100.00, @context['100.00']
205
- end
206
-
207
- def test_strings
208
- assert_equal "hello!", @context['"hello!"']
209
- assert_equal "hello!", @context["'hello!'"]
210
- end
211
-
212
- def test_merge
213
- @context.merge({ "test" => "test" })
214
- assert_equal 'test', @context['test']
215
- @context.merge({ "test" => "newvalue", "foo" => "bar" })
216
- assert_equal 'newvalue', @context['test']
217
- assert_equal 'bar', @context['foo']
218
- end
219
-
220
- def test_array_notation
221
- @context['test'] = [1, 2, 3, 4, 5]
222
-
223
- assert_equal 1, @context['test[0]']
224
- assert_equal 2, @context['test[1]']
225
- assert_equal 3, @context['test[2]']
226
- assert_equal 4, @context['test[3]']
227
- assert_equal 5, @context['test[4]']
228
- end
229
-
230
- def test_recoursive_array_notation
231
- @context['test'] = { 'test' => [1, 2, 3, 4, 5] }
232
-
233
- assert_equal 1, @context['test.test[0]']
234
-
235
- @context['test'] = [{ 'test' => 'worked' }]
236
-
237
- assert_equal 'worked', @context['test[0].test']
238
- end
239
-
240
- def test_hash_to_array_transition
241
- @context['colors'] = {
242
- 'Blue' => ['003366', '336699', '6699CC', '99CCFF'],
243
- 'Green' => ['003300', '336633', '669966', '99CC99'],
244
- 'Yellow' => ['CC9900', 'FFCC00', 'FFFF99', 'FFFFCC'],
245
- 'Red' => ['660000', '993333', 'CC6666', 'FF9999']
246
- }
247
-
248
- assert_equal '003366', @context['colors.Blue[0]']
249
- assert_equal 'FF9999', @context['colors.Red[3]']
250
- end
251
-
252
- def test_try_first
253
- @context['test'] = [1, 2, 3, 4, 5]
254
-
255
- assert_equal 1, @context['test.first']
256
- assert_equal 5, @context['test.last']
257
-
258
- @context['test'] = { 'test' => [1, 2, 3, 4, 5] }
259
-
260
- assert_equal 1, @context['test.test.first']
261
- assert_equal 5, @context['test.test.last']
262
-
263
- @context['test'] = [1]
264
- assert_equal 1, @context['test.first']
265
- assert_equal 1, @context['test.last']
266
- end
267
-
268
- def test_access_hashes_with_hash_notation
269
- @context['products'] = { 'count' => 5, 'tags' => ['deepsnow', 'freestyle'] }
270
- @context['product'] = { 'variants' => [ { 'title' => 'draft151cm' }, { 'title' => 'element151cm' } ] }
271
-
272
- assert_equal 5, @context['products["count"]']
273
- assert_equal 'deepsnow', @context['products["tags"][0]']
274
- assert_equal 'deepsnow', @context['products["tags"].first']
275
- assert_equal 'draft151cm', @context['product["variants"][0]["title"]']
276
- assert_equal 'element151cm', @context['product["variants"][1]["title"]']
277
- assert_equal 'draft151cm', @context['product["variants"][0]["title"]']
278
- assert_equal 'element151cm', @context['product["variants"].last["title"]']
279
- end
280
-
281
- def test_access_variable_with_hash_notation
282
- @context['foo'] = 'baz'
283
- @context['bar'] = 'foo'
284
-
285
- assert_equal 'baz', @context['["foo"]']
286
- assert_equal 'baz', @context['[bar]']
287
- end
288
-
289
- def test_access_hashes_with_hash_access_variables
290
- @context['var'] = 'tags'
291
- @context['nested'] = { 'var' => 'tags' }
292
- @context['products'] = { 'count' => 5, 'tags' => ['deepsnow', 'freestyle'] }
293
-
294
- assert_equal 'deepsnow', @context['products[var].first']
295
- assert_equal 'freestyle', @context['products[nested.var].last']
296
- end
297
-
298
- def test_hash_notation_only_for_hash_access
299
- @context['array'] = [1, 2, 3, 4, 5]
300
- @context['hash'] = { 'first' => 'Hello' }
301
-
302
- assert_equal 1, @context['array.first']
303
- assert_equal nil, @context['array["first"]']
304
- assert_equal 'Hello', @context['hash["first"]']
305
- end
306
-
307
- def test_first_can_appear_in_middle_of_callchain
308
- @context['product'] = { 'variants' => [ { 'title' => 'draft151cm' }, { 'title' => 'element151cm' } ] }
309
-
310
- assert_equal 'draft151cm', @context['product.variants[0].title']
311
- assert_equal 'element151cm', @context['product.variants[1].title']
312
- assert_equal 'draft151cm', @context['product.variants.first.title']
313
- assert_equal 'element151cm', @context['product.variants.last.title']
314
- end
315
-
316
- def test_cents
317
- @context.merge("cents" => HundredCentes.new)
318
- assert_equal 100, @context['cents']
319
- end
320
-
321
- def test_nested_cents
322
- @context.merge("cents" => { 'amount' => HundredCentes.new })
323
- assert_equal 100, @context['cents.amount']
324
-
325
- @context.merge("cents" => { 'cents' => { 'amount' => HundredCentes.new } })
326
- assert_equal 100, @context['cents.cents.amount']
327
- end
328
-
329
- def test_cents_through_drop
330
- @context.merge("cents" => CentsDrop.new)
331
- assert_equal 100, @context['cents.amount']
332
- end
333
-
334
- def test_nested_cents_through_drop
335
- @context.merge("vars" => { "cents" => CentsDrop.new })
336
- assert_equal 100, @context['vars.cents.amount']
337
- end
338
-
339
- def test_drop_methods_with_question_marks
340
- @context.merge("cents" => CentsDrop.new)
341
- assert @context['cents.non_zero?']
342
- end
343
-
344
- def test_context_from_within_drop
345
- @context.merge("test" => '123', "vars" => ContextSensitiveDrop.new)
346
- assert_equal '123', @context['vars.test']
347
- end
348
-
349
- def test_nested_context_from_within_drop
350
- @context.merge("test" => '123', "vars" => { "local" => ContextSensitiveDrop.new })
351
- assert_equal '123', @context['vars.local.test']
352
- end
353
-
354
- def test_ranges
355
- @context.merge("test" => '5')
356
- assert_equal (1..5), @context['(1..5)']
357
- assert_equal (1..5), @context['(1..test)']
358
- assert_equal (5..5), @context['(test..test)']
359
- end
360
-
361
- def test_cents_through_drop_nestedly
362
- @context.merge("cents" => { "cents" => CentsDrop.new })
363
- assert_equal 100, @context['cents.cents.amount']
364
-
365
- @context.merge("cents" => { "cents" => { "cents" => CentsDrop.new } })
366
- assert_equal 100, @context['cents.cents.cents.amount']
367
- end
368
-
369
- def test_drop_with_variable_called_only_once
370
- @context['counter'] = CounterDrop.new
371
-
372
- assert_equal 1, @context['counter.count']
373
- assert_equal 2, @context['counter.count']
374
- assert_equal 3, @context['counter.count']
375
- end
376
-
377
- def test_drop_with_key_called_only_once
378
- @context['counter'] = CounterDrop.new
379
-
380
- assert_equal 1, @context['counter["count"]']
381
- assert_equal 2, @context['counter["count"]']
382
- assert_equal 3, @context['counter["count"]']
383
- end
384
-
385
- def test_proc_as_variable
386
- @context['dynamic'] = proc { 'Hello' }
387
-
388
- assert_equal 'Hello', @context['dynamic']
389
- end
390
-
391
- def test_lambda_as_variable
392
- @context['dynamic'] = proc { 'Hello' }
393
-
394
- assert_equal 'Hello', @context['dynamic']
395
- end
396
-
397
- def test_nested_lambda_as_variable
398
- @context['dynamic'] = { "lambda" => proc { 'Hello' } }
399
-
400
- assert_equal 'Hello', @context['dynamic.lambda']
401
- end
402
-
403
- def test_array_containing_lambda_as_variable
404
- @context['dynamic'] = [1, 2, proc { 'Hello' }, 4, 5]
405
-
406
- assert_equal 'Hello', @context['dynamic[2]']
407
- end
408
-
409
- def test_lambda_is_called_once
410
- @context['callcount'] = proc { @global ||= 0; @global += 1; @global.to_s }
411
-
412
- assert_equal '1', @context['callcount']
413
- assert_equal '1', @context['callcount']
414
- assert_equal '1', @context['callcount']
415
-
416
- @global = nil
417
- end
418
-
419
- def test_nested_lambda_is_called_once
420
- @context['callcount'] = { "lambda" => proc { @global ||= 0; @global += 1; @global.to_s } }
421
-
422
- assert_equal '1', @context['callcount.lambda']
423
- assert_equal '1', @context['callcount.lambda']
424
- assert_equal '1', @context['callcount.lambda']
425
-
426
- @global = nil
427
- end
428
-
429
- def test_lambda_in_array_is_called_once
430
- @context['callcount'] = [1, 2, proc { @global ||= 0; @global += 1; @global.to_s }, 4, 5]
431
-
432
- assert_equal '1', @context['callcount[2]']
433
- assert_equal '1', @context['callcount[2]']
434
- assert_equal '1', @context['callcount[2]']
435
-
436
- @global = nil
437
- end
438
-
439
- def test_access_to_context_from_proc
440
- @context.registers[:magic] = 345392
441
-
442
- @context['magic'] = proc { @context.registers[:magic] }
443
-
444
- assert_equal 345392, @context['magic']
445
- end
446
-
447
- def test_to_liquid_and_context_at_first_level
448
- @context['category'] = Category.new("foobar")
449
- assert_kind_of CategoryDrop, @context['category']
450
- assert_equal @context, @context['category'].context
451
- end
452
-
453
- def test_use_empty_instead_of_any_in_interrupt_handling_to_avoid_lots_of_unnecessary_object_allocations
454
- mock_any = Spy.on_instance_method(Array, :any?)
455
- mock_empty = Spy.on_instance_method(Array, :empty?)
456
-
457
- @context.interrupt?
458
-
459
- refute mock_any.has_been_called?
460
- assert mock_empty.has_been_called?
461
- end
462
-
463
- def test_context_initialization_with_a_proc_in_environment
464
- contx = Context.new([test: ->(c) { c['poutine'] }], { test: :foo })
465
-
466
- assert contx
467
- assert_nil contx['poutine']
468
- end
469
-
470
- def test_apply_global_filter
471
- global_filter_proc = ->(output) { "#{output} filtered" }
472
-
473
- context = Context.new
474
- context.global_filter = global_filter_proc
475
-
476
- assert_equal 'hi filtered', context.apply_global_filter('hi')
477
- end
478
-
479
- def test_apply_global_filter_when_no_global_filter_exist
480
- context = Context.new
481
- assert_equal 'hi', context.apply_global_filter('hi')
482
- end
483
- end # ContextTest