liquid 3.0.6 → 5.4.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 (113) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +243 -58
  3. data/README.md +43 -4
  4. data/lib/liquid/block.rb +57 -123
  5. data/lib/liquid/block_body.rb +217 -85
  6. data/lib/liquid/condition.rb +92 -45
  7. data/lib/liquid/context.rb +154 -89
  8. data/lib/liquid/document.rb +57 -9
  9. data/lib/liquid/drop.rb +20 -17
  10. data/lib/liquid/errors.rb +27 -29
  11. data/lib/liquid/expression.rb +32 -20
  12. data/lib/liquid/extensions.rb +21 -7
  13. data/lib/liquid/file_system.rb +17 -15
  14. data/lib/liquid/forloop_drop.rb +92 -0
  15. data/lib/liquid/i18n.rb +10 -8
  16. data/lib/liquid/interrupts.rb +4 -3
  17. data/lib/liquid/lexer.rb +37 -26
  18. data/lib/liquid/locales/en.yml +13 -6
  19. data/lib/liquid/parse_context.rb +54 -0
  20. data/lib/liquid/parse_tree_visitor.rb +42 -0
  21. data/lib/liquid/parser.rb +30 -18
  22. data/lib/liquid/parser_switching.rb +20 -6
  23. data/lib/liquid/partial_cache.rb +24 -0
  24. data/lib/liquid/profiler/hooks.rb +26 -14
  25. data/lib/liquid/profiler.rb +72 -92
  26. data/lib/liquid/range_lookup.rb +28 -3
  27. data/lib/liquid/registers.rb +51 -0
  28. data/lib/liquid/resource_limits.rb +62 -0
  29. data/lib/liquid/standardfilters.rb +715 -132
  30. data/lib/liquid/strainer_factory.rb +41 -0
  31. data/lib/liquid/strainer_template.rb +62 -0
  32. data/lib/liquid/tablerowloop_drop.rb +121 -0
  33. data/lib/liquid/tag/disableable.rb +22 -0
  34. data/lib/liquid/tag/disabler.rb +21 -0
  35. data/lib/liquid/tag.rb +35 -12
  36. data/lib/liquid/tags/assign.rb +57 -18
  37. data/lib/liquid/tags/break.rb +15 -5
  38. data/lib/liquid/tags/capture.rb +24 -18
  39. data/lib/liquid/tags/case.rb +79 -30
  40. data/lib/liquid/tags/comment.rb +19 -4
  41. data/lib/liquid/tags/continue.rb +16 -12
  42. data/lib/liquid/tags/cycle.rb +47 -27
  43. data/lib/liquid/tags/decrement.rb +23 -24
  44. data/lib/liquid/tags/echo.rb +41 -0
  45. data/lib/liquid/tags/for.rb +155 -124
  46. data/lib/liquid/tags/if.rb +97 -63
  47. data/lib/liquid/tags/ifchanged.rb +11 -12
  48. data/lib/liquid/tags/include.rb +82 -73
  49. data/lib/liquid/tags/increment.rb +23 -17
  50. data/lib/liquid/tags/inline_comment.rb +43 -0
  51. data/lib/liquid/tags/raw.rb +50 -8
  52. data/lib/liquid/tags/render.rb +109 -0
  53. data/lib/liquid/tags/table_row.rb +57 -41
  54. data/lib/liquid/tags/unless.rb +38 -20
  55. data/lib/liquid/template.rb +71 -103
  56. data/lib/liquid/template_factory.rb +9 -0
  57. data/lib/liquid/tokenizer.rb +39 -0
  58. data/lib/liquid/usage.rb +8 -0
  59. data/lib/liquid/utils.rb +63 -9
  60. data/lib/liquid/variable.rb +74 -56
  61. data/lib/liquid/variable_lookup.rb +31 -15
  62. data/lib/liquid/version.rb +3 -1
  63. data/lib/liquid.rb +27 -12
  64. metadata +30 -106
  65. data/lib/liquid/module_ex.rb +0 -62
  66. data/lib/liquid/strainer.rb +0 -59
  67. data/lib/liquid/token.rb +0 -18
  68. data/test/fixtures/en_locale.yml +0 -9
  69. data/test/integration/assign_test.rb +0 -48
  70. data/test/integration/blank_test.rb +0 -106
  71. data/test/integration/capture_test.rb +0 -50
  72. data/test/integration/context_test.rb +0 -32
  73. data/test/integration/drop_test.rb +0 -271
  74. data/test/integration/error_handling_test.rb +0 -207
  75. data/test/integration/filter_test.rb +0 -138
  76. data/test/integration/hash_ordering_test.rb +0 -23
  77. data/test/integration/output_test.rb +0 -124
  78. data/test/integration/parsing_quirks_test.rb +0 -116
  79. data/test/integration/render_profiling_test.rb +0 -154
  80. data/test/integration/security_test.rb +0 -64
  81. data/test/integration/standard_filter_test.rb +0 -396
  82. data/test/integration/tags/break_tag_test.rb +0 -16
  83. data/test/integration/tags/continue_tag_test.rb +0 -16
  84. data/test/integration/tags/for_tag_test.rb +0 -375
  85. data/test/integration/tags/if_else_tag_test.rb +0 -190
  86. data/test/integration/tags/include_tag_test.rb +0 -234
  87. data/test/integration/tags/increment_tag_test.rb +0 -24
  88. data/test/integration/tags/raw_tag_test.rb +0 -25
  89. data/test/integration/tags/standard_tag_test.rb +0 -297
  90. data/test/integration/tags/statements_test.rb +0 -113
  91. data/test/integration/tags/table_row_test.rb +0 -63
  92. data/test/integration/tags/unless_else_tag_test.rb +0 -26
  93. data/test/integration/template_test.rb +0 -182
  94. data/test/integration/variable_test.rb +0 -82
  95. data/test/test_helper.rb +0 -89
  96. data/test/unit/block_unit_test.rb +0 -55
  97. data/test/unit/condition_unit_test.rb +0 -149
  98. data/test/unit/context_unit_test.rb +0 -492
  99. data/test/unit/file_system_unit_test.rb +0 -35
  100. data/test/unit/i18n_unit_test.rb +0 -37
  101. data/test/unit/lexer_unit_test.rb +0 -48
  102. data/test/unit/module_ex_unit_test.rb +0 -87
  103. data/test/unit/parser_unit_test.rb +0 -82
  104. data/test/unit/regexp_unit_test.rb +0 -44
  105. data/test/unit/strainer_unit_test.rb +0 -69
  106. data/test/unit/tag_unit_test.rb +0 -16
  107. data/test/unit/tags/case_tag_unit_test.rb +0 -10
  108. data/test/unit/tags/for_tag_unit_test.rb +0 -13
  109. data/test/unit/tags/if_tag_unit_test.rb +0 -8
  110. data/test/unit/template_unit_test.rb +0 -69
  111. data/test/unit/tokenizer_unit_test.rb +0 -38
  112. data/test/unit/variable_unit_test.rb +0 -145
  113. /data/{MIT-LICENSE → LICENSE} +0 -0
@@ -1,149 +0,0 @@
1
- require 'test_helper'
2
-
3
- class ConditionUnitTest < Minitest::Test
4
- include Liquid
5
-
6
- def test_basic_condition
7
- assert_equal false, Condition.new('1', '==', '2').evaluate
8
- assert_equal true, Condition.new('1', '==', '1').evaluate
9
- end
10
-
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'
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'
26
- end
27
-
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'
38
- end
39
-
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', "'---'"
50
- end
51
-
52
- def test_invalid_comparation_operator
53
- assert_evaluates_argument_error "1", '~~', '0'
54
- end
55
-
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'
61
- end
62
-
63
- def test_contains_works_on_arrays
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"'
75
- end
76
-
77
- def test_contains_returns_false_for_nil_operands
78
- @context = Liquid::Context.new
79
- assert_evalutes_false "not_assigned", 'contains', '0'
80
- assert_evalutes_false "0", 'contains', 'not_assigned'
81
- end
82
-
83
- def test_contains_return_false_on_wrong_data_type
84
- assert_evalutes_false "1", 'contains', '0'
85
- end
86
-
87
- def test_or_condition
88
- condition = Condition.new('1', '==', '2')
89
-
90
- assert_equal false, condition.evaluate
91
-
92
- condition.or Condition.new('2', '==', '1')
93
-
94
- assert_equal false, condition.evaluate
95
-
96
- condition.or Condition.new('1', '==', '1')
97
-
98
- assert_equal true, condition.evaluate
99
- end
100
-
101
- def test_and_condition
102
- condition = Condition.new('1', '==', '1')
103
-
104
- assert_equal true, condition.evaluate
105
-
106
- condition.and Condition.new('2', '==', '2')
107
-
108
- assert_equal true, condition.evaluate
109
-
110
- condition.and Condition.new('2', '==', '1')
111
-
112
- assert_equal false, condition.evaluate
113
- end
114
-
115
- 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'"
120
-
121
- ensure
122
- Condition.operators.delete 'starts_with'
123
- end
124
-
125
- def test_left_or_right_may_contain_operators
126
- @context = Liquid::Context.new
127
- @context['one'] = @context['another'] = "gnomeslab-and-or-liquid"
128
-
129
- assert_evalutes_true "one", '==', "another"
130
- end
131
-
132
- 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
- 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
142
-
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
148
-
149
- end # ConditionTest
@@ -1,492 +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
-
126
- @context['numbers'] = [1,2,3,4]
127
-
128
- assert_equal 4, @context['numbers.size']
129
-
130
- @context['numbers'] = {1 => 1,2 => 2,3 => 3,4 => 4}
131
-
132
- assert_equal 4, @context['numbers.size']
133
-
134
- @context['numbers'] = {1 => 1,2 => 2,3 => 3,4 => 4, 'size' => 1000}
135
-
136
- assert_equal 1000, @context['numbers.size']
137
-
138
- end
139
-
140
- def test_hyphenated_variable
141
-
142
- @context['oh-my'] = 'godz'
143
- assert_equal 'godz', @context['oh-my']
144
-
145
- end
146
-
147
- def test_add_filter
148
-
149
- filter = Module.new do
150
- def hi(output)
151
- output + ' hi!'
152
- end
153
- end
154
-
155
- context = Context.new
156
- context.add_filters(filter)
157
- assert_equal 'hi? hi!', context.invoke(:hi, 'hi?')
158
-
159
- context = Context.new
160
- assert_equal 'hi?', context.invoke(:hi, 'hi?')
161
-
162
- context.add_filters(filter)
163
- assert_equal 'hi? hi!', context.invoke(:hi, 'hi?')
164
-
165
- end
166
-
167
- def test_only_intended_filters_make_it_there
168
-
169
- filter = Module.new do
170
- def hi(output)
171
- output + ' hi!'
172
- end
173
- end
174
-
175
- context = Context.new
176
- assert_equal "Wookie", context.invoke("hi", "Wookie")
177
-
178
- context.add_filters(filter)
179
- assert_equal "Wookie hi!", context.invoke("hi", "Wookie")
180
- end
181
-
182
- def test_add_item_in_outer_scope
183
- @context['test'] = 'test'
184
- @context.push
185
- assert_equal 'test', @context['test']
186
- @context.pop
187
- assert_equal 'test', @context['test']
188
- end
189
-
190
- def test_add_item_in_inner_scope
191
- @context.push
192
- @context['test'] = 'test'
193
- assert_equal 'test', @context['test']
194
- @context.pop
195
- assert_equal nil, @context['test']
196
- end
197
-
198
- def test_hierachical_data
199
- @context['hash'] = {"name" => 'tobi'}
200
- assert_equal 'tobi', @context['hash.name']
201
- assert_equal 'tobi', @context['hash["name"]']
202
- end
203
-
204
- def test_keywords
205
- assert_equal true, @context['true']
206
- assert_equal false, @context['false']
207
- end
208
-
209
- def test_digits
210
- assert_equal 100, @context['100']
211
- assert_equal 100.00, @context['100.00']
212
- end
213
-
214
- def test_strings
215
- assert_equal "hello!", @context['"hello!"']
216
- assert_equal "hello!", @context["'hello!'"]
217
- end
218
-
219
- def test_merge
220
- @context.merge({ "test" => "test" })
221
- assert_equal 'test', @context['test']
222
- @context.merge({ "test" => "newvalue", "foo" => "bar" })
223
- assert_equal 'newvalue', @context['test']
224
- assert_equal 'bar', @context['foo']
225
- end
226
-
227
- def test_array_notation
228
- @context['test'] = [1,2,3,4,5]
229
-
230
- assert_equal 1, @context['test[0]']
231
- assert_equal 2, @context['test[1]']
232
- assert_equal 3, @context['test[2]']
233
- assert_equal 4, @context['test[3]']
234
- assert_equal 5, @context['test[4]']
235
- end
236
-
237
- def test_recoursive_array_notation
238
- @context['test'] = {'test' => [1,2,3,4,5]}
239
-
240
- assert_equal 1, @context['test.test[0]']
241
-
242
- @context['test'] = [{'test' => 'worked'}]
243
-
244
- assert_equal 'worked', @context['test[0].test']
245
- end
246
-
247
- def test_hash_to_array_transition
248
- @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']
253
- }
254
-
255
- assert_equal '003366', @context['colors.Blue[0]']
256
- assert_equal 'FF9999', @context['colors.Red[3]']
257
- end
258
-
259
- def test_try_first
260
- @context['test'] = [1,2,3,4,5]
261
-
262
- assert_equal 1, @context['test.first']
263
- assert_equal 5, @context['test.last']
264
-
265
- @context['test'] = {'test' => [1,2,3,4,5]}
266
-
267
- assert_equal 1, @context['test.test.first']
268
- assert_equal 5, @context['test.test.last']
269
-
270
- @context['test'] = [1]
271
- assert_equal 1, @context['test.first']
272
- assert_equal 1, @context['test.last']
273
- end
274
-
275
- def test_access_hashes_with_hash_notation
276
- @context['products'] = {'count' => 5, 'tags' => ['deepsnow', 'freestyle'] }
277
- @context['product'] = {'variants' => [ {'title' => 'draft151cm'}, {'title' => 'element151cm'} ]}
278
-
279
- assert_equal 5, @context['products["count"]']
280
- assert_equal 'deepsnow', @context['products["tags"][0]']
281
- assert_equal 'deepsnow', @context['products["tags"].first']
282
- assert_equal 'draft151cm', @context['product["variants"][0]["title"]']
283
- assert_equal 'element151cm', @context['product["variants"][1]["title"]']
284
- assert_equal 'draft151cm', @context['product["variants"][0]["title"]']
285
- assert_equal 'element151cm', @context['product["variants"].last["title"]']
286
- end
287
-
288
- def test_access_variable_with_hash_notation
289
- @context['foo'] = 'baz'
290
- @context['bar'] = 'foo'
291
-
292
- assert_equal 'baz', @context['["foo"]']
293
- assert_equal 'baz', @context['[bar]']
294
- end
295
-
296
- def test_access_hashes_with_hash_access_variables
297
-
298
- @context['var'] = 'tags'
299
- @context['nested'] = {'var' => 'tags'}
300
- @context['products'] = {'count' => 5, 'tags' => ['deepsnow', 'freestyle'] }
301
-
302
- assert_equal 'deepsnow', @context['products[var].first']
303
- assert_equal 'freestyle', @context['products[nested.var].last']
304
- end
305
-
306
- def test_hash_notation_only_for_hash_access
307
- @context['array'] = [1,2,3,4,5]
308
- @context['hash'] = {'first' => 'Hello'}
309
-
310
- assert_equal 1, @context['array.first']
311
- assert_equal nil, @context['array["first"]']
312
- assert_equal 'Hello', @context['hash["first"]']
313
- end
314
-
315
- def test_first_can_appear_in_middle_of_callchain
316
-
317
- @context['product'] = {'variants' => [ {'title' => 'draft151cm'}, {'title' => 'element151cm'} ]}
318
-
319
- assert_equal 'draft151cm', @context['product.variants[0].title']
320
- assert_equal 'element151cm', @context['product.variants[1].title']
321
- assert_equal 'draft151cm', @context['product.variants.first.title']
322
- assert_equal 'element151cm', @context['product.variants.last.title']
323
-
324
- end
325
-
326
- def test_cents
327
- @context.merge( "cents" => HundredCentes.new )
328
- assert_equal 100, @context['cents']
329
- end
330
-
331
- def test_nested_cents
332
- @context.merge( "cents" => { 'amount' => HundredCentes.new} )
333
- assert_equal 100, @context['cents.amount']
334
-
335
- @context.merge( "cents" => { 'cents' => { 'amount' => HundredCentes.new} } )
336
- assert_equal 100, @context['cents.cents.amount']
337
- end
338
-
339
- def test_cents_through_drop
340
- @context.merge( "cents" => CentsDrop.new )
341
- assert_equal 100, @context['cents.amount']
342
- end
343
-
344
- def test_nested_cents_through_drop
345
- @context.merge( "vars" => {"cents" => CentsDrop.new} )
346
- assert_equal 100, @context['vars.cents.amount']
347
- end
348
-
349
- def test_drop_methods_with_question_marks
350
- @context.merge( "cents" => CentsDrop.new )
351
- assert @context['cents.non_zero?']
352
- end
353
-
354
- def test_context_from_within_drop
355
- @context.merge( "test" => '123', "vars" => ContextSensitiveDrop.new )
356
- assert_equal '123', @context['vars.test']
357
- end
358
-
359
- def test_nested_context_from_within_drop
360
- @context.merge( "test" => '123', "vars" => {"local" => ContextSensitiveDrop.new } )
361
- assert_equal '123', @context['vars.local.test']
362
- end
363
-
364
- def test_ranges
365
- @context.merge( "test" => '5' )
366
- assert_equal (1..5), @context['(1..5)']
367
- assert_equal (1..5), @context['(1..test)']
368
- assert_equal (5..5), @context['(test..test)']
369
- end
370
-
371
- def test_cents_through_drop_nestedly
372
- @context.merge( "cents" => {"cents" => CentsDrop.new} )
373
- assert_equal 100, @context['cents.cents.amount']
374
-
375
- @context.merge( "cents" => { "cents" => {"cents" => CentsDrop.new}} )
376
- assert_equal 100, @context['cents.cents.cents.amount']
377
- end
378
-
379
- def test_drop_with_variable_called_only_once
380
- @context['counter'] = CounterDrop.new
381
-
382
- assert_equal 1, @context['counter.count']
383
- assert_equal 2, @context['counter.count']
384
- assert_equal 3, @context['counter.count']
385
- end
386
-
387
- def test_drop_with_key_called_only_once
388
- @context['counter'] = CounterDrop.new
389
-
390
- assert_equal 1, @context['counter["count"]']
391
- assert_equal 2, @context['counter["count"]']
392
- assert_equal 3, @context['counter["count"]']
393
- end
394
-
395
- def test_proc_as_variable
396
- @context['dynamic'] = Proc.new { 'Hello' }
397
-
398
- assert_equal 'Hello', @context['dynamic']
399
- end
400
-
401
- def test_lambda_as_variable
402
- @context['dynamic'] = proc { 'Hello' }
403
-
404
- assert_equal 'Hello', @context['dynamic']
405
- end
406
-
407
- def test_nested_lambda_as_variable
408
- @context['dynamic'] = { "lambda" => proc { 'Hello' } }
409
-
410
- assert_equal 'Hello', @context['dynamic.lambda']
411
- end
412
-
413
- def test_array_containing_lambda_as_variable
414
- @context['dynamic'] = [1,2, proc { 'Hello' } ,4,5]
415
-
416
- assert_equal 'Hello', @context['dynamic[2]']
417
- end
418
-
419
- def test_lambda_is_called_once
420
- @context['callcount'] = proc { @global ||= 0; @global += 1; @global.to_s }
421
-
422
- assert_equal '1', @context['callcount']
423
- assert_equal '1', @context['callcount']
424
- assert_equal '1', @context['callcount']
425
-
426
- @global = nil
427
- end
428
-
429
- def test_nested_lambda_is_called_once
430
- @context['callcount'] = { "lambda" => proc { @global ||= 0; @global += 1; @global.to_s } }
431
-
432
- assert_equal '1', @context['callcount.lambda']
433
- assert_equal '1', @context['callcount.lambda']
434
- assert_equal '1', @context['callcount.lambda']
435
-
436
- @global = nil
437
- end
438
-
439
- def test_lambda_in_array_is_called_once
440
- @context['callcount'] = [1,2, proc { @global ||= 0; @global += 1; @global.to_s } ,4,5]
441
-
442
- assert_equal '1', @context['callcount[2]']
443
- assert_equal '1', @context['callcount[2]']
444
- assert_equal '1', @context['callcount[2]']
445
-
446
- @global = nil
447
- end
448
-
449
- def test_access_to_context_from_proc
450
- @context.registers[:magic] = 345392
451
-
452
- @context['magic'] = proc { @context.registers[:magic] }
453
-
454
- assert_equal 345392, @context['magic']
455
- end
456
-
457
- def test_to_liquid_and_context_at_first_level
458
- @context['category'] = Category.new("foobar")
459
- assert_kind_of CategoryDrop, @context['category']
460
- assert_equal @context, @context['category'].context
461
- end
462
-
463
- def test_use_empty_instead_of_any_in_interrupt_handling_to_avoid_lots_of_unnecessary_object_allocations
464
- mock_any = Spy.on_instance_method(Array, :any?)
465
- mock_empty = Spy.on_instance_method(Array, :empty?)
466
- mock_has_interrupt = Spy.on(@context, :has_interrupt?).and_call_through
467
-
468
- @context.has_interrupt?
469
-
470
- refute mock_any.has_been_called?
471
- 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
- end
483
-
484
- def test_context_initialization_with_a_proc_in_environment
485
- contx = Context.new([:test => lambda { |c| c['poutine']}], {:test => :foo})
486
-
487
- assert contx
488
- assert_nil contx['poutine']
489
- end
490
-
491
-
492
- end # ContextTest
@@ -1,35 +0,0 @@
1
- require 'test_helper'
2
-
3
- class FileSystemUnitTest < Minitest::Test
4
- include Liquid
5
-
6
- def test_default
7
- assert_raises(FileSystemError) do
8
- BlankFileSystem.new.read_template_file("dummy", {'dummy'=>'smarty'})
9
- end
10
- end
11
-
12
- def test_local
13
- file_system = Liquid::LocalFileSystem.new("/some/path")
14
- assert_equal "/some/path/_mypartial.liquid" , file_system.full_path("mypartial")
15
- assert_equal "/some/path/dir/_mypartial.liquid", file_system.full_path("dir/mypartial")
16
-
17
- assert_raises(FileSystemError) do
18
- file_system.full_path("../dir/mypartial")
19
- end
20
-
21
- assert_raises(FileSystemError) do
22
- file_system.full_path("/dir/../../dir/mypartial")
23
- end
24
-
25
- assert_raises(FileSystemError) do
26
- file_system.full_path("/etc/passwd")
27
- end
28
- end
29
-
30
- def test_custom_template_filename_patterns
31
- file_system = Liquid::LocalFileSystem.new("/some/path", "%s.html")
32
- assert_equal "/some/path/mypartial.html" , file_system.full_path("mypartial")
33
- assert_equal "/some/path/dir/mypartial.html", file_system.full_path("dir/mypartial")
34
- end
35
- end # FileSystemTest