liquid 3.0.6 → 5.4.0

Sign up to get free protection for your applications and to get access to all the features.
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