liquid 4.0.0 → 5.10.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 (117) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +235 -2
  3. data/README.md +58 -8
  4. data/lib/liquid/block.rb +51 -20
  5. data/lib/liquid/block_body.rb +216 -82
  6. data/lib/liquid/condition.rb +83 -32
  7. data/lib/liquid/const.rb +8 -0
  8. data/lib/liquid/context.rb +130 -59
  9. data/lib/liquid/deprecations.rb +22 -0
  10. data/lib/liquid/document.rb +47 -9
  11. data/lib/liquid/drop.rb +8 -2
  12. data/lib/liquid/environment.rb +159 -0
  13. data/lib/liquid/errors.rb +23 -20
  14. data/lib/liquid/expression.rb +114 -31
  15. data/lib/liquid/extensions.rb +8 -0
  16. data/lib/liquid/file_system.rb +6 -4
  17. data/lib/liquid/forloop_drop.rb +51 -4
  18. data/lib/liquid/i18n.rb +5 -3
  19. data/lib/liquid/interrupts.rb +3 -1
  20. data/lib/liquid/lexer.rb +165 -39
  21. data/lib/liquid/locales/en.yml +16 -6
  22. data/lib/liquid/parse_context.rb +62 -7
  23. data/lib/liquid/parse_tree_visitor.rb +42 -0
  24. data/lib/liquid/parser.rb +31 -19
  25. data/lib/liquid/parser_switching.rb +42 -3
  26. data/lib/liquid/partial_cache.rb +33 -0
  27. data/lib/liquid/profiler/hooks.rb +26 -14
  28. data/lib/liquid/profiler.rb +67 -86
  29. data/lib/liquid/range_lookup.rb +26 -6
  30. data/lib/liquid/registers.rb +51 -0
  31. data/lib/liquid/resource_limits.rb +47 -8
  32. data/lib/liquid/snippet_drop.rb +22 -0
  33. data/lib/liquid/standardfilters.rb +813 -137
  34. data/lib/liquid/strainer_template.rb +62 -0
  35. data/lib/liquid/tablerowloop_drop.rb +64 -5
  36. data/lib/liquid/tag/disableable.rb +22 -0
  37. data/lib/liquid/tag/disabler.rb +13 -0
  38. data/lib/liquid/tag.rb +42 -6
  39. data/lib/liquid/tags/assign.rb +46 -18
  40. data/lib/liquid/tags/break.rb +15 -4
  41. data/lib/liquid/tags/capture.rb +26 -18
  42. data/lib/liquid/tags/case.rb +108 -32
  43. data/lib/liquid/tags/comment.rb +76 -4
  44. data/lib/liquid/tags/continue.rb +15 -13
  45. data/lib/liquid/tags/cycle.rb +117 -34
  46. data/lib/liquid/tags/decrement.rb +30 -23
  47. data/lib/liquid/tags/doc.rb +81 -0
  48. data/lib/liquid/tags/echo.rb +39 -0
  49. data/lib/liquid/tags/for.rb +109 -96
  50. data/lib/liquid/tags/if.rb +72 -41
  51. data/lib/liquid/tags/ifchanged.rb +10 -11
  52. data/lib/liquid/tags/include.rb +89 -63
  53. data/lib/liquid/tags/increment.rb +31 -20
  54. data/lib/liquid/tags/inline_comment.rb +28 -0
  55. data/lib/liquid/tags/raw.rb +25 -13
  56. data/lib/liquid/tags/render.rb +151 -0
  57. data/lib/liquid/tags/snippet.rb +45 -0
  58. data/lib/liquid/tags/table_row.rb +104 -21
  59. data/lib/liquid/tags/unless.rb +37 -20
  60. data/lib/liquid/tags.rb +51 -0
  61. data/lib/liquid/template.rb +90 -106
  62. data/lib/liquid/template_factory.rb +9 -0
  63. data/lib/liquid/tokenizer.rb +143 -13
  64. data/lib/liquid/usage.rb +8 -0
  65. data/lib/liquid/utils.rb +114 -5
  66. data/lib/liquid/variable.rb +119 -45
  67. data/lib/liquid/variable_lookup.rb +35 -13
  68. data/lib/liquid/version.rb +3 -1
  69. data/lib/liquid.rb +31 -18
  70. metadata +56 -107
  71. data/lib/liquid/strainer.rb +0 -66
  72. data/test/fixtures/en_locale.yml +0 -9
  73. data/test/integration/assign_test.rb +0 -48
  74. data/test/integration/blank_test.rb +0 -106
  75. data/test/integration/capture_test.rb +0 -50
  76. data/test/integration/context_test.rb +0 -32
  77. data/test/integration/document_test.rb +0 -19
  78. data/test/integration/drop_test.rb +0 -273
  79. data/test/integration/error_handling_test.rb +0 -260
  80. data/test/integration/filter_test.rb +0 -178
  81. data/test/integration/hash_ordering_test.rb +0 -23
  82. data/test/integration/output_test.rb +0 -123
  83. data/test/integration/parsing_quirks_test.rb +0 -118
  84. data/test/integration/render_profiling_test.rb +0 -154
  85. data/test/integration/security_test.rb +0 -66
  86. data/test/integration/standard_filter_test.rb +0 -535
  87. data/test/integration/tags/break_tag_test.rb +0 -15
  88. data/test/integration/tags/continue_tag_test.rb +0 -15
  89. data/test/integration/tags/for_tag_test.rb +0 -410
  90. data/test/integration/tags/if_else_tag_test.rb +0 -188
  91. data/test/integration/tags/include_tag_test.rb +0 -238
  92. data/test/integration/tags/increment_tag_test.rb +0 -23
  93. data/test/integration/tags/raw_tag_test.rb +0 -31
  94. data/test/integration/tags/standard_tag_test.rb +0 -296
  95. data/test/integration/tags/statements_test.rb +0 -111
  96. data/test/integration/tags/table_row_test.rb +0 -64
  97. data/test/integration/tags/unless_else_tag_test.rb +0 -26
  98. data/test/integration/template_test.rb +0 -323
  99. data/test/integration/trim_mode_test.rb +0 -525
  100. data/test/integration/variable_test.rb +0 -92
  101. data/test/test_helper.rb +0 -117
  102. data/test/unit/block_unit_test.rb +0 -58
  103. data/test/unit/condition_unit_test.rb +0 -158
  104. data/test/unit/context_unit_test.rb +0 -483
  105. data/test/unit/file_system_unit_test.rb +0 -35
  106. data/test/unit/i18n_unit_test.rb +0 -37
  107. data/test/unit/lexer_unit_test.rb +0 -51
  108. data/test/unit/parser_unit_test.rb +0 -82
  109. data/test/unit/regexp_unit_test.rb +0 -44
  110. data/test/unit/strainer_unit_test.rb +0 -148
  111. data/test/unit/tag_unit_test.rb +0 -21
  112. data/test/unit/tags/case_tag_unit_test.rb +0 -10
  113. data/test/unit/tags/for_tag_unit_test.rb +0 -13
  114. data/test/unit/tags/if_tag_unit_test.rb +0 -8
  115. data/test/unit/template_unit_test.rb +0 -78
  116. data/test/unit/tokenizer_unit_test.rb +0 -55
  117. data/test/unit/variable_unit_test.rb +0 -162
@@ -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
@@ -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")
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
@@ -1,37 +0,0 @@
1
- require 'test_helper'
2
-
3
- class I18nUnitTest < Minitest::Test
4
- include Liquid
5
-
6
- def setup
7
- @i18n = I18n.new(fixture("en_locale.yml"))
8
- end
9
-
10
- def test_simple_translate_string
11
- assert_equal "less is more", @i18n.translate("simple")
12
- end
13
-
14
- def test_nested_translate_string
15
- assert_equal "something wasn't right", @i18n.translate("errors.syntax.oops")
16
- end
17
-
18
- def test_single_string_interpolation
19
- assert_equal "something different", @i18n.translate("whatever", something: "different")
20
- end
21
-
22
- # def test_raises_translation_error_on_undefined_interpolation_key
23
- # assert_raises I18n::TranslationError do
24
- # @i18n.translate("whatever", :oopstypos => "yes")
25
- # end
26
- # end
27
-
28
- def test_raises_unknown_translation
29
- assert_raises I18n::TranslationError do
30
- @i18n.translate("doesnt_exist")
31
- end
32
- end
33
-
34
- def test_sets_default_path_to_en
35
- assert_equal I18n::DEFAULT_LOCALE, I18n.new.path
36
- end
37
- end
@@ -1,51 +0,0 @@
1
- require 'test_helper'
2
-
3
- class LexerUnitTest < Minitest::Test
4
- include Liquid
5
-
6
- def test_strings
7
- tokens = Lexer.new(%( 'this is a test""' "wat 'lol'")).tokenize
8
- assert_equal [[:string, %('this is a test""')], [:string, %("wat 'lol'")], [:end_of_string]], tokens
9
- end
10
-
11
- def test_integer
12
- tokens = Lexer.new('hi 50').tokenize
13
- assert_equal [[:id, 'hi'], [:number, '50'], [:end_of_string]], tokens
14
- end
15
-
16
- def test_float
17
- tokens = Lexer.new('hi 5.0').tokenize
18
- assert_equal [[:id, 'hi'], [:number, '5.0'], [:end_of_string]], tokens
19
- end
20
-
21
- def test_comparison
22
- tokens = Lexer.new('== <> contains').tokenize
23
- assert_equal [[:comparison, '=='], [:comparison, '<>'], [:comparison, 'contains'], [:end_of_string]], tokens
24
- end
25
-
26
- def test_specials
27
- tokens = Lexer.new('| .:').tokenize
28
- assert_equal [[:pipe, '|'], [:dot, '.'], [:colon, ':'], [:end_of_string]], tokens
29
- tokens = Lexer.new('[,]').tokenize
30
- assert_equal [[:open_square, '['], [:comma, ','], [:close_square, ']'], [:end_of_string]], tokens
31
- end
32
-
33
- def test_fancy_identifiers
34
- tokens = Lexer.new('hi five?').tokenize
35
- assert_equal [[:id, 'hi'], [:id, 'five?'], [:end_of_string]], tokens
36
-
37
- tokens = Lexer.new('2foo').tokenize
38
- assert_equal [[:number, '2'], [:id, 'foo'], [:end_of_string]], tokens
39
- end
40
-
41
- def test_whitespace
42
- tokens = Lexer.new("five|\n\t ==").tokenize
43
- assert_equal [[:id, 'five'], [:pipe, '|'], [:comparison, '=='], [:end_of_string]], tokens
44
- end
45
-
46
- def test_unexpected_character
47
- assert_raises(SyntaxError) do
48
- Lexer.new("%").tokenize
49
- end
50
- end
51
- end
@@ -1,82 +0,0 @@
1
- require 'test_helper'
2
-
3
- class ParserUnitTest < Minitest::Test
4
- include Liquid
5
-
6
- def test_consume
7
- p = Parser.new("wat: 7")
8
- assert_equal 'wat', p.consume(:id)
9
- assert_equal ':', p.consume(:colon)
10
- assert_equal '7', p.consume(:number)
11
- end
12
-
13
- def test_jump
14
- p = Parser.new("wat: 7")
15
- p.jump(2)
16
- assert_equal '7', p.consume(:number)
17
- end
18
-
19
- def test_consume?
20
- p = Parser.new("wat: 7")
21
- assert_equal 'wat', p.consume?(:id)
22
- assert_equal false, p.consume?(:dot)
23
- assert_equal ':', p.consume(:colon)
24
- assert_equal '7', p.consume?(:number)
25
- end
26
-
27
- def test_id?
28
- p = Parser.new("wat 6 Peter Hegemon")
29
- assert_equal 'wat', p.id?('wat')
30
- assert_equal false, p.id?('endgame')
31
- assert_equal '6', p.consume(:number)
32
- assert_equal 'Peter', p.id?('Peter')
33
- assert_equal false, p.id?('Achilles')
34
- end
35
-
36
- def test_look
37
- p = Parser.new("wat 6 Peter Hegemon")
38
- assert_equal true, p.look(:id)
39
- assert_equal 'wat', p.consume(:id)
40
- assert_equal false, p.look(:comparison)
41
- assert_equal true, p.look(:number)
42
- assert_equal true, p.look(:id, 1)
43
- assert_equal false, p.look(:number, 1)
44
- end
45
-
46
- def test_expressions
47
- p = Parser.new("hi.there hi?[5].there? hi.there.bob")
48
- assert_equal 'hi.there', p.expression
49
- assert_equal 'hi?[5].there?', p.expression
50
- assert_equal 'hi.there.bob', p.expression
51
-
52
- p = Parser.new("567 6.0 'lol' \"wut\"")
53
- assert_equal '567', p.expression
54
- assert_equal '6.0', p.expression
55
- assert_equal "'lol'", p.expression
56
- assert_equal '"wut"', p.expression
57
- end
58
-
59
- def test_ranges
60
- p = Parser.new("(5..7) (1.5..9.6) (young..old) (hi[5].wat..old)")
61
- assert_equal '(5..7)', p.expression
62
- assert_equal '(1.5..9.6)', p.expression
63
- assert_equal '(young..old)', p.expression
64
- assert_equal '(hi[5].wat..old)', p.expression
65
- end
66
-
67
- def test_arguments
68
- p = Parser.new("filter: hi.there[5], keyarg: 7")
69
- assert_equal 'filter', p.consume(:id)
70
- assert_equal ':', p.consume(:colon)
71
- assert_equal 'hi.there[5]', p.argument
72
- assert_equal ',', p.consume(:comma)
73
- assert_equal 'keyarg: 7', p.argument
74
- end
75
-
76
- def test_invalid_expression
77
- assert_raises(SyntaxError) do
78
- p = Parser.new("==")
79
- p.expression
80
- end
81
- end
82
- end