liquid 3.0.6 → 4.0.0.rc1

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 (95) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +89 -58
  3. data/{MIT-LICENSE → LICENSE} +0 -0
  4. data/lib/liquid.rb +7 -6
  5. data/lib/liquid/block.rb +31 -124
  6. data/lib/liquid/block_body.rb +54 -57
  7. data/lib/liquid/condition.rb +23 -22
  8. data/lib/liquid/context.rb +50 -42
  9. data/lib/liquid/document.rb +19 -9
  10. data/lib/liquid/drop.rb +12 -13
  11. data/lib/liquid/errors.rb +16 -17
  12. data/lib/liquid/expression.rb +15 -3
  13. data/lib/liquid/extensions.rb +7 -7
  14. data/lib/liquid/file_system.rb +3 -3
  15. data/lib/liquid/forloop_drop.rb +42 -0
  16. data/lib/liquid/i18n.rb +5 -5
  17. data/lib/liquid/interrupts.rb +1 -2
  18. data/lib/liquid/lexer.rb +6 -4
  19. data/lib/liquid/locales/en.yml +3 -1
  20. data/lib/liquid/parse_context.rb +37 -0
  21. data/lib/liquid/parser_switching.rb +4 -4
  22. data/lib/liquid/profiler.rb +18 -19
  23. data/lib/liquid/profiler/hooks.rb +7 -7
  24. data/lib/liquid/range_lookup.rb +16 -1
  25. data/lib/liquid/resource_limits.rb +23 -0
  26. data/lib/liquid/standardfilters.rb +101 -56
  27. data/lib/liquid/strainer.rb +4 -5
  28. data/lib/liquid/tablerowloop_drop.rb +62 -0
  29. data/lib/liquid/tag.rb +9 -8
  30. data/lib/liquid/tags/assign.rb +5 -4
  31. data/lib/liquid/tags/break.rb +0 -3
  32. data/lib/liquid/tags/capture.rb +1 -1
  33. data/lib/liquid/tags/case.rb +19 -12
  34. data/lib/liquid/tags/comment.rb +2 -2
  35. data/lib/liquid/tags/cycle.rb +6 -6
  36. data/lib/liquid/tags/decrement.rb +1 -4
  37. data/lib/liquid/tags/for.rb +93 -75
  38. data/lib/liquid/tags/if.rb +49 -44
  39. data/lib/liquid/tags/ifchanged.rb +0 -2
  40. data/lib/liquid/tags/include.rb +60 -52
  41. data/lib/liquid/tags/raw.rb +26 -4
  42. data/lib/liquid/tags/table_row.rb +12 -30
  43. data/lib/liquid/tags/unless.rb +3 -4
  44. data/lib/liquid/template.rb +23 -50
  45. data/lib/liquid/tokenizer.rb +31 -0
  46. data/lib/liquid/utils.rb +48 -8
  47. data/lib/liquid/variable.rb +46 -45
  48. data/lib/liquid/variable_lookup.rb +3 -3
  49. data/lib/liquid/version.rb +1 -1
  50. data/test/integration/assign_test.rb +8 -8
  51. data/test/integration/blank_test.rb +14 -14
  52. data/test/integration/context_test.rb +2 -2
  53. data/test/integration/document_test.rb +19 -0
  54. data/test/integration/drop_test.rb +42 -40
  55. data/test/integration/error_handling_test.rb +64 -45
  56. data/test/integration/filter_test.rb +60 -20
  57. data/test/integration/output_test.rb +26 -27
  58. data/test/integration/parsing_quirks_test.rb +15 -13
  59. data/test/integration/render_profiling_test.rb +20 -20
  60. data/test/integration/security_test.rb +5 -7
  61. data/test/integration/standard_filter_test.rb +119 -37
  62. data/test/integration/tags/break_tag_test.rb +1 -2
  63. data/test/integration/tags/continue_tag_test.rb +0 -1
  64. data/test/integration/tags/for_tag_test.rb +133 -98
  65. data/test/integration/tags/if_else_tag_test.rb +75 -77
  66. data/test/integration/tags/include_tag_test.rb +23 -30
  67. data/test/integration/tags/increment_tag_test.rb +10 -11
  68. data/test/integration/tags/raw_tag_test.rb +7 -1
  69. data/test/integration/tags/standard_tag_test.rb +121 -122
  70. data/test/integration/tags/statements_test.rb +3 -5
  71. data/test/integration/tags/table_row_test.rb +20 -19
  72. data/test/integration/tags/unless_else_tag_test.rb +6 -6
  73. data/test/integration/template_test.rb +91 -45
  74. data/test/integration/variable_test.rb +23 -13
  75. data/test/test_helper.rb +33 -5
  76. data/test/unit/block_unit_test.rb +6 -5
  77. data/test/unit/condition_unit_test.rb +82 -77
  78. data/test/unit/context_unit_test.rb +48 -57
  79. data/test/unit/file_system_unit_test.rb +3 -3
  80. data/test/unit/i18n_unit_test.rb +2 -2
  81. data/test/unit/lexer_unit_test.rb +11 -8
  82. data/test/unit/parser_unit_test.rb +2 -2
  83. data/test/unit/regexp_unit_test.rb +1 -1
  84. data/test/unit/strainer_unit_test.rb +13 -2
  85. data/test/unit/tag_unit_test.rb +7 -2
  86. data/test/unit/tags/case_tag_unit_test.rb +1 -1
  87. data/test/unit/tags/for_tag_unit_test.rb +2 -2
  88. data/test/unit/tags/if_tag_unit_test.rb +1 -1
  89. data/test/unit/template_unit_test.rb +6 -5
  90. data/test/unit/tokenizer_unit_test.rb +24 -7
  91. data/test/unit/variable_unit_test.rb +60 -43
  92. metadata +44 -41
  93. data/lib/liquid/module_ex.rb +0 -62
  94. data/lib/liquid/token.rb +0 -18
  95. data/test/unit/module_ex_unit_test.rb +0 -87
@@ -34,7 +34,7 @@ class BlockUnitTest < Minitest::Test
34
34
  template = Liquid::Template.parse(" {{funk}} {{so}} {{brother}} ")
35
35
  assert_equal 7, template.root.nodelist.size
36
36
  assert_equal [String, Variable, String, Variable, String, Variable, String],
37
- block_types(template.root.nodelist)
37
+ block_types(template.root.nodelist)
38
38
  end
39
39
 
40
40
  def test_with_block
@@ -45,11 +45,12 @@ class BlockUnitTest < Minitest::Test
45
45
 
46
46
  def test_with_custom_tag
47
47
  Liquid::Template.register_tag("testtag", Block)
48
- assert Liquid::Template.parse( "{% testtag %} {% endtesttag %}")
48
+ assert Liquid::Template.parse("{% testtag %} {% endtesttag %}")
49
49
  end
50
50
 
51
51
  private
52
- def block_types(nodelist)
53
- nodelist.collect { |node| node.class }
54
- end
52
+
53
+ def block_types(nodelist)
54
+ nodelist.collect(&:class)
55
+ end
55
56
  end # VariableTest
@@ -4,146 +4,151 @@ class ConditionUnitTest < Minitest::Test
4
4
  include Liquid
5
5
 
6
6
  def test_basic_condition
7
- assert_equal false, Condition.new('1', '==', '2').evaluate
8
- assert_equal true, Condition.new('1', '==', '1').evaluate
7
+ assert_equal false, Condition.new(1, '==', 2).evaluate
8
+ assert_equal true, Condition.new(1, '==', 1).evaluate
9
9
  end
10
10
 
11
11
  def test_default_operators_evalute_true
12
- assert_evalutes_true '1', '==', '1'
13
- assert_evalutes_true '1', '!=', '2'
14
- assert_evalutes_true '1', '<>', '2'
15
- assert_evalutes_true '1', '<', '2'
16
- assert_evalutes_true '2', '>', '1'
17
- assert_evalutes_true '1', '>=', '1'
18
- assert_evalutes_true '2', '>=', '1'
19
- assert_evalutes_true '1', '<=', '2'
20
- assert_evalutes_true '1', '<=', '1'
12
+ assert_evalutes_true 1, '==', 1
13
+ assert_evalutes_true 1, '!=', 2
14
+ assert_evalutes_true 1, '<>', 2
15
+ assert_evalutes_true 1, '<', 2
16
+ assert_evalutes_true 2, '>', 1
17
+ assert_evalutes_true 1, '>=', 1
18
+ assert_evalutes_true 2, '>=', 1
19
+ assert_evalutes_true 1, '<=', 2
20
+ assert_evalutes_true 1, '<=', 1
21
21
  # negative numbers
22
- assert_evalutes_true '1', '>', '-1'
23
- assert_evalutes_true '-1', '<', '1'
24
- assert_evalutes_true '1.0', '>', '-1.0'
25
- assert_evalutes_true '-1.0', '<', '1.0'
22
+ assert_evalutes_true 1, '>', -1
23
+ assert_evalutes_true -1, '<', 1
24
+ assert_evalutes_true 1.0, '>', -1.0
25
+ assert_evalutes_true -1.0, '<', 1.0
26
26
  end
27
27
 
28
28
  def test_default_operators_evalute_false
29
- assert_evalutes_false '1', '==', '2'
30
- assert_evalutes_false '1', '!=', '1'
31
- assert_evalutes_false '1', '<>', '1'
32
- assert_evalutes_false '1', '<', '0'
33
- assert_evalutes_false '2', '>', '4'
34
- assert_evalutes_false '1', '>=', '3'
35
- assert_evalutes_false '2', '>=', '4'
36
- assert_evalutes_false '1', '<=', '0'
37
- assert_evalutes_false '1', '<=', '0'
29
+ assert_evalutes_false 1, '==', 2
30
+ assert_evalutes_false 1, '!=', 1
31
+ assert_evalutes_false 1, '<>', 1
32
+ assert_evalutes_false 1, '<', 0
33
+ assert_evalutes_false 2, '>', 4
34
+ assert_evalutes_false 1, '>=', 3
35
+ assert_evalutes_false 2, '>=', 4
36
+ assert_evalutes_false 1, '<=', 0
37
+ assert_evalutes_false 1, '<=', 0
38
38
  end
39
39
 
40
40
  def test_contains_works_on_strings
41
- assert_evalutes_true "'bob'", 'contains', "'o'"
42
- assert_evalutes_true "'bob'", 'contains', "'b'"
43
- assert_evalutes_true "'bob'", 'contains', "'bo'"
44
- assert_evalutes_true "'bob'", 'contains', "'ob'"
45
- assert_evalutes_true "'bob'", 'contains', "'bob'"
46
-
47
- assert_evalutes_false "'bob'", 'contains', "'bob2'"
48
- assert_evalutes_false "'bob'", 'contains', "'a'"
49
- assert_evalutes_false "'bob'", 'contains', "'---'"
41
+ assert_evalutes_true 'bob', 'contains', 'o'
42
+ assert_evalutes_true 'bob', 'contains', 'b'
43
+ assert_evalutes_true 'bob', 'contains', 'bo'
44
+ assert_evalutes_true 'bob', 'contains', 'ob'
45
+ assert_evalutes_true 'bob', 'contains', 'bob'
46
+
47
+ assert_evalutes_false 'bob', 'contains', 'bob2'
48
+ assert_evalutes_false 'bob', 'contains', 'a'
49
+ assert_evalutes_false 'bob', 'contains', '---'
50
50
  end
51
51
 
52
52
  def test_invalid_comparation_operator
53
- assert_evaluates_argument_error "1", '~~', '0'
53
+ assert_evaluates_argument_error 1, '~~', 0
54
54
  end
55
55
 
56
56
  def test_comparation_of_int_and_str
57
- assert_evaluates_argument_error "'1'", '>', '0'
58
- assert_evaluates_argument_error "'1'", '<', '0'
59
- assert_evaluates_argument_error "'1'", '>=', '0'
60
- assert_evaluates_argument_error "'1'", '<=', '0'
57
+ assert_evaluates_argument_error '1', '>', 0
58
+ assert_evaluates_argument_error '1', '<', 0
59
+ assert_evaluates_argument_error '1', '>=', 0
60
+ assert_evaluates_argument_error '1', '<=', 0
61
61
  end
62
62
 
63
63
  def test_contains_works_on_arrays
64
64
  @context = Liquid::Context.new
65
- @context['array'] = [1,2,3,4,5]
66
-
67
- assert_evalutes_false "array", 'contains', '0'
68
- assert_evalutes_true "array", 'contains', '1'
69
- assert_evalutes_true "array", 'contains', '2'
70
- assert_evalutes_true "array", 'contains', '3'
71
- assert_evalutes_true "array", 'contains', '4'
72
- assert_evalutes_true "array", 'contains', '5'
73
- assert_evalutes_false "array", 'contains', '6'
74
- assert_evalutes_false "array", 'contains', '"1"'
65
+ @context['array'] = [1, 2, 3, 4, 5]
66
+ array_expr = VariableLookup.new("array")
67
+
68
+ assert_evalutes_false array_expr, 'contains', 0
69
+ assert_evalutes_true array_expr, 'contains', 1
70
+ assert_evalutes_true array_expr, 'contains', 2
71
+ assert_evalutes_true array_expr, 'contains', 3
72
+ assert_evalutes_true array_expr, 'contains', 4
73
+ assert_evalutes_true array_expr, 'contains', 5
74
+ assert_evalutes_false array_expr, 'contains', 6
75
+ assert_evalutes_false array_expr, 'contains', "1"
75
76
  end
76
77
 
77
78
  def test_contains_returns_false_for_nil_operands
78
79
  @context = Liquid::Context.new
79
- assert_evalutes_false "not_assigned", 'contains', '0'
80
- assert_evalutes_false "0", 'contains', 'not_assigned'
80
+ assert_evalutes_false VariableLookup.new('not_assigned'), 'contains', '0'
81
+ assert_evalutes_false 0, 'contains', VariableLookup.new('not_assigned')
81
82
  end
82
83
 
83
84
  def test_contains_return_false_on_wrong_data_type
84
- assert_evalutes_false "1", 'contains', '0'
85
+ assert_evalutes_false 1, 'contains', 0
86
+ end
87
+
88
+ def test_contains_with_string_left_operand_coerces_right_operand_to_string
89
+ assert_evalutes_true ' 1 ', 'contains', 1
90
+ assert_evalutes_false ' 1 ', 'contains', 2
85
91
  end
86
92
 
87
93
  def test_or_condition
88
- condition = Condition.new('1', '==', '2')
94
+ condition = Condition.new(1, '==', 2)
89
95
 
90
96
  assert_equal false, condition.evaluate
91
97
 
92
- condition.or Condition.new('2', '==', '1')
98
+ condition.or Condition.new(2, '==', 1)
93
99
 
94
100
  assert_equal false, condition.evaluate
95
101
 
96
- condition.or Condition.new('1', '==', '1')
102
+ condition.or Condition.new(1, '==', 1)
97
103
 
98
104
  assert_equal true, condition.evaluate
99
105
  end
100
106
 
101
107
  def test_and_condition
102
- condition = Condition.new('1', '==', '1')
108
+ condition = Condition.new(1, '==', 1)
103
109
 
104
110
  assert_equal true, condition.evaluate
105
111
 
106
- condition.and Condition.new('2', '==', '2')
112
+ condition.and Condition.new(2, '==', 2)
107
113
 
108
114
  assert_equal true, condition.evaluate
109
115
 
110
- condition.and Condition.new('2', '==', '1')
116
+ condition.and Condition.new(2, '==', 1)
111
117
 
112
118
  assert_equal false, condition.evaluate
113
119
  end
114
120
 
115
121
  def test_should_allow_custom_proc_operator
116
- Condition.operators['starts_with'] = Proc.new { |cond, left, right| left =~ %r{^#{right}} }
117
-
118
- assert_evalutes_true "'bob'", 'starts_with', "'b'"
119
- assert_evalutes_false "'bob'", 'starts_with', "'o'"
122
+ Condition.operators['starts_with'] = proc { |cond, left, right| left =~ %r{^#{right}} }
120
123
 
121
- ensure
122
- Condition.operators.delete 'starts_with'
124
+ assert_evalutes_true 'bob', 'starts_with', 'b'
125
+ assert_evalutes_false 'bob', 'starts_with', 'o'
126
+ ensure
127
+ Condition.operators.delete 'starts_with'
123
128
  end
124
129
 
125
130
  def test_left_or_right_may_contain_operators
126
131
  @context = Liquid::Context.new
127
132
  @context['one'] = @context['another'] = "gnomeslab-and-or-liquid"
128
133
 
129
- assert_evalutes_true "one", '==', "another"
134
+ assert_evalutes_true VariableLookup.new("one"), '==', VariableLookup.new("another")
130
135
  end
131
136
 
132
137
  private
133
- def assert_evalutes_true(left, op, right)
134
- assert Condition.new(left, op, right).evaluate(@context || Liquid::Context.new),
135
- "Evaluated false: #{left} #{op} #{right}"
136
- end
137
138
 
138
- def assert_evalutes_false(left, op, right)
139
- assert !Condition.new(left, op, right).evaluate(@context || Liquid::Context.new),
140
- "Evaluated true: #{left} #{op} #{right}"
141
- end
139
+ def assert_evalutes_true(left, op, right)
140
+ assert Condition.new(left, op, right).evaluate(@context || Liquid::Context.new),
141
+ "Evaluated false: #{left} #{op} #{right}"
142
+ end
142
143
 
143
- def assert_evaluates_argument_error(left, op, right)
144
- assert_raises(Liquid::ArgumentError) do
145
- Condition.new(left, op, right).evaluate(@context || Liquid::Context.new)
146
- end
147
- end
144
+ def assert_evalutes_false(left, op, right)
145
+ assert !Condition.new(left, op, right).evaluate(@context || Liquid::Context.new),
146
+ "Evaluated true: #{left} #{op} #{right}"
147
+ end
148
148
 
149
+ def assert_evaluates_argument_error(left, op, right)
150
+ assert_raises(Liquid::ArgumentError) do
151
+ Condition.new(left, op, right).evaluate(@context || Liquid::Context.new)
152
+ end
153
+ end
149
154
  end # ConditionTest
@@ -122,30 +122,25 @@ class ContextUnitTest < Minitest::Test
122
122
  end
123
123
 
124
124
  def test_length_query
125
-
126
- @context['numbers'] = [1,2,3,4]
125
+ @context['numbers'] = [1, 2, 3, 4]
127
126
 
128
127
  assert_equal 4, @context['numbers.size']
129
128
 
130
- @context['numbers'] = {1 => 1,2 => 2,3 => 3,4 => 4}
129
+ @context['numbers'] = { 1 => 1, 2 => 2, 3 => 3, 4 => 4 }
131
130
 
132
131
  assert_equal 4, @context['numbers.size']
133
132
 
134
- @context['numbers'] = {1 => 1,2 => 2,3 => 3,4 => 4, 'size' => 1000}
133
+ @context['numbers'] = { 1 => 1, 2 => 2, 3 => 3, 4 => 4, 'size' => 1000 }
135
134
 
136
135
  assert_equal 1000, @context['numbers.size']
137
-
138
136
  end
139
137
 
140
138
  def test_hyphenated_variable
141
-
142
139
  @context['oh-my'] = 'godz'
143
140
  assert_equal 'godz', @context['oh-my']
144
-
145
141
  end
146
142
 
147
143
  def test_add_filter
148
-
149
144
  filter = Module.new do
150
145
  def hi(output)
151
146
  output + ' hi!'
@@ -161,11 +156,9 @@ class ContextUnitTest < Minitest::Test
161
156
 
162
157
  context.add_filters(filter)
163
158
  assert_equal 'hi? hi!', context.invoke(:hi, 'hi?')
164
-
165
159
  end
166
160
 
167
161
  def test_only_intended_filters_make_it_there
168
-
169
162
  filter = Module.new do
170
163
  def hi(output)
171
164
  output + ' hi!'
@@ -196,7 +189,7 @@ class ContextUnitTest < Minitest::Test
196
189
  end
197
190
 
198
191
  def test_hierachical_data
199
- @context['hash'] = {"name" => 'tobi'}
192
+ @context['hash'] = { "name" => 'tobi' }
200
193
  assert_equal 'tobi', @context['hash.name']
201
194
  assert_equal 'tobi', @context['hash["name"]']
202
195
  end
@@ -225,7 +218,7 @@ class ContextUnitTest < Minitest::Test
225
218
  end
226
219
 
227
220
  def test_array_notation
228
- @context['test'] = [1,2,3,4,5]
221
+ @context['test'] = [1, 2, 3, 4, 5]
229
222
 
230
223
  assert_equal 1, @context['test[0]']
231
224
  assert_equal 2, @context['test[1]']
@@ -235,21 +228,21 @@ class ContextUnitTest < Minitest::Test
235
228
  end
236
229
 
237
230
  def test_recoursive_array_notation
238
- @context['test'] = {'test' => [1,2,3,4,5]}
231
+ @context['test'] = { 'test' => [1, 2, 3, 4, 5] }
239
232
 
240
233
  assert_equal 1, @context['test.test[0]']
241
234
 
242
- @context['test'] = [{'test' => 'worked'}]
235
+ @context['test'] = [{ 'test' => 'worked' }]
243
236
 
244
237
  assert_equal 'worked', @context['test[0].test']
245
238
  end
246
239
 
247
240
  def test_hash_to_array_transition
248
241
  @context['colors'] = {
249
- 'Blue' => ['003366','336699', '6699CC', '99CCFF'],
250
- 'Green' => ['003300','336633', '669966', '99CC99'],
251
- 'Yellow' => ['CC9900','FFCC00', 'FFFF99', 'FFFFCC'],
252
- 'Red' => ['660000','993333', 'CC6666', 'FF9999']
242
+ 'Blue' => ['003366', '336699', '6699CC', '99CCFF'],
243
+ 'Green' => ['003300', '336633', '669966', '99CC99'],
244
+ 'Yellow' => ['CC9900', 'FFCC00', 'FFFF99', 'FFFFCC'],
245
+ 'Red' => ['660000', '993333', 'CC6666', 'FF9999']
253
246
  }
254
247
 
255
248
  assert_equal '003366', @context['colors.Blue[0]']
@@ -257,12 +250,12 @@ class ContextUnitTest < Minitest::Test
257
250
  end
258
251
 
259
252
  def test_try_first
260
- @context['test'] = [1,2,3,4,5]
253
+ @context['test'] = [1, 2, 3, 4, 5]
261
254
 
262
255
  assert_equal 1, @context['test.first']
263
256
  assert_equal 5, @context['test.last']
264
257
 
265
- @context['test'] = {'test' => [1,2,3,4,5]}
258
+ @context['test'] = { 'test' => [1, 2, 3, 4, 5] }
266
259
 
267
260
  assert_equal 1, @context['test.test.first']
268
261
  assert_equal 5, @context['test.test.last']
@@ -273,8 +266,8 @@ class ContextUnitTest < Minitest::Test
273
266
  end
274
267
 
275
268
  def test_access_hashes_with_hash_notation
276
- @context['products'] = {'count' => 5, 'tags' => ['deepsnow', 'freestyle'] }
277
- @context['product'] = {'variants' => [ {'title' => 'draft151cm'}, {'title' => 'element151cm'} ]}
269
+ @context['products'] = { 'count' => 5, 'tags' => ['deepsnow', 'freestyle'] }
270
+ @context['product'] = { 'variants' => [ { 'title' => 'draft151cm' }, { 'title' => 'element151cm' } ] }
278
271
 
279
272
  assert_equal 5, @context['products["count"]']
280
273
  assert_equal 'deepsnow', @context['products["tags"][0]']
@@ -294,18 +287,17 @@ class ContextUnitTest < Minitest::Test
294
287
  end
295
288
 
296
289
  def test_access_hashes_with_hash_access_variables
297
-
298
290
  @context['var'] = 'tags'
299
- @context['nested'] = {'var' => 'tags'}
300
- @context['products'] = {'count' => 5, 'tags' => ['deepsnow', 'freestyle'] }
291
+ @context['nested'] = { 'var' => 'tags' }
292
+ @context['products'] = { 'count' => 5, 'tags' => ['deepsnow', 'freestyle'] }
301
293
 
302
294
  assert_equal 'deepsnow', @context['products[var].first']
303
295
  assert_equal 'freestyle', @context['products[nested.var].last']
304
296
  end
305
297
 
306
298
  def test_hash_notation_only_for_hash_access
307
- @context['array'] = [1,2,3,4,5]
308
- @context['hash'] = {'first' => 'Hello'}
299
+ @context['array'] = [1, 2, 3, 4, 5]
300
+ @context['hash'] = { 'first' => 'Hello' }
309
301
 
310
302
  assert_equal 1, @context['array.first']
311
303
  assert_equal nil, @context['array["first"]']
@@ -313,66 +305,64 @@ class ContextUnitTest < Minitest::Test
313
305
  end
314
306
 
315
307
  def test_first_can_appear_in_middle_of_callchain
316
-
317
- @context['product'] = {'variants' => [ {'title' => 'draft151cm'}, {'title' => 'element151cm'} ]}
308
+ @context['product'] = { 'variants' => [ { 'title' => 'draft151cm' }, { 'title' => 'element151cm' } ] }
318
309
 
319
310
  assert_equal 'draft151cm', @context['product.variants[0].title']
320
311
  assert_equal 'element151cm', @context['product.variants[1].title']
321
312
  assert_equal 'draft151cm', @context['product.variants.first.title']
322
313
  assert_equal 'element151cm', @context['product.variants.last.title']
323
-
324
314
  end
325
315
 
326
316
  def test_cents
327
- @context.merge( "cents" => HundredCentes.new )
317
+ @context.merge("cents" => HundredCentes.new)
328
318
  assert_equal 100, @context['cents']
329
319
  end
330
320
 
331
321
  def test_nested_cents
332
- @context.merge( "cents" => { 'amount' => HundredCentes.new} )
322
+ @context.merge("cents" => { 'amount' => HundredCentes.new })
333
323
  assert_equal 100, @context['cents.amount']
334
324
 
335
- @context.merge( "cents" => { 'cents' => { 'amount' => HundredCentes.new} } )
325
+ @context.merge("cents" => { 'cents' => { 'amount' => HundredCentes.new } })
336
326
  assert_equal 100, @context['cents.cents.amount']
337
327
  end
338
328
 
339
329
  def test_cents_through_drop
340
- @context.merge( "cents" => CentsDrop.new )
330
+ @context.merge("cents" => CentsDrop.new)
341
331
  assert_equal 100, @context['cents.amount']
342
332
  end
343
333
 
344
334
  def test_nested_cents_through_drop
345
- @context.merge( "vars" => {"cents" => CentsDrop.new} )
335
+ @context.merge("vars" => { "cents" => CentsDrop.new })
346
336
  assert_equal 100, @context['vars.cents.amount']
347
337
  end
348
338
 
349
339
  def test_drop_methods_with_question_marks
350
- @context.merge( "cents" => CentsDrop.new )
340
+ @context.merge("cents" => CentsDrop.new)
351
341
  assert @context['cents.non_zero?']
352
342
  end
353
343
 
354
344
  def test_context_from_within_drop
355
- @context.merge( "test" => '123', "vars" => ContextSensitiveDrop.new )
345
+ @context.merge("test" => '123', "vars" => ContextSensitiveDrop.new)
356
346
  assert_equal '123', @context['vars.test']
357
347
  end
358
348
 
359
349
  def test_nested_context_from_within_drop
360
- @context.merge( "test" => '123', "vars" => {"local" => ContextSensitiveDrop.new } )
350
+ @context.merge("test" => '123', "vars" => { "local" => ContextSensitiveDrop.new })
361
351
  assert_equal '123', @context['vars.local.test']
362
352
  end
363
353
 
364
354
  def test_ranges
365
- @context.merge( "test" => '5' )
355
+ @context.merge("test" => '5')
366
356
  assert_equal (1..5), @context['(1..5)']
367
357
  assert_equal (1..5), @context['(1..test)']
368
358
  assert_equal (5..5), @context['(test..test)']
369
359
  end
370
360
 
371
361
  def test_cents_through_drop_nestedly
372
- @context.merge( "cents" => {"cents" => CentsDrop.new} )
362
+ @context.merge("cents" => { "cents" => CentsDrop.new })
373
363
  assert_equal 100, @context['cents.cents.amount']
374
364
 
375
- @context.merge( "cents" => { "cents" => {"cents" => CentsDrop.new}} )
365
+ @context.merge("cents" => { "cents" => { "cents" => CentsDrop.new } })
376
366
  assert_equal 100, @context['cents.cents.cents.amount']
377
367
  end
378
368
 
@@ -393,7 +383,7 @@ class ContextUnitTest < Minitest::Test
393
383
  end
394
384
 
395
385
  def test_proc_as_variable
396
- @context['dynamic'] = Proc.new { 'Hello' }
386
+ @context['dynamic'] = proc { 'Hello' }
397
387
 
398
388
  assert_equal 'Hello', @context['dynamic']
399
389
  end
@@ -411,7 +401,7 @@ class ContextUnitTest < Minitest::Test
411
401
  end
412
402
 
413
403
  def test_array_containing_lambda_as_variable
414
- @context['dynamic'] = [1,2, proc { 'Hello' } ,4,5]
404
+ @context['dynamic'] = [1, 2, proc { 'Hello' }, 4, 5]
415
405
 
416
406
  assert_equal 'Hello', @context['dynamic[2]']
417
407
  end
@@ -437,7 +427,7 @@ class ContextUnitTest < Minitest::Test
437
427
  end
438
428
 
439
429
  def test_lambda_in_array_is_called_once
440
- @context['callcount'] = [1,2, proc { @global ||= 0; @global += 1; @global.to_s } ,4,5]
430
+ @context['callcount'] = [1, 2, proc { @global ||= 0; @global += 1; @global.to_s }, 4, 5]
441
431
 
442
432
  assert_equal '1', @context['callcount[2]']
443
433
  assert_equal '1', @context['callcount[2]']
@@ -463,30 +453,31 @@ class ContextUnitTest < Minitest::Test
463
453
  def test_use_empty_instead_of_any_in_interrupt_handling_to_avoid_lots_of_unnecessary_object_allocations
464
454
  mock_any = Spy.on_instance_method(Array, :any?)
465
455
  mock_empty = Spy.on_instance_method(Array, :empty?)
466
- mock_has_interrupt = Spy.on(@context, :has_interrupt?).and_call_through
467
456
 
468
- @context.has_interrupt?
457
+ @context.interrupt?
469
458
 
470
459
  refute mock_any.has_been_called?
471
460
  assert mock_empty.has_been_called?
472
- end
473
-
474
- def test_variable_lookup_caches_markup
475
- mock_scan = Spy.on_instance_method(String, :scan).and_return(["string"])
476
-
477
- @context['string'] = 'string'
478
- @context['string']
479
- @context['string']
480
-
481
- assert_equal 1, mock_scan.calls.size
482
461
  end
483
462
 
484
463
  def test_context_initialization_with_a_proc_in_environment
485
- contx = Context.new([:test => lambda { |c| c['poutine']}], {:test => :foo})
464
+ contx = Context.new([test: ->(c) { c['poutine'] }], { test: :foo })
486
465
 
487
466
  assert contx
488
467
  assert_nil contx['poutine']
489
468
  end
490
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
491
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
492
483
  end # ContextTest