liquid 4.0.3 → 5.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +89 -0
  3. data/README.md +10 -4
  4. data/lib/liquid/block.rb +31 -14
  5. data/lib/liquid/block_body.rb +169 -57
  6. data/lib/liquid/condition.rb +48 -21
  7. data/lib/liquid/context.rb +111 -52
  8. data/lib/liquid/document.rb +47 -9
  9. data/lib/liquid/drop.rb +4 -2
  10. data/lib/liquid/errors.rb +20 -18
  11. data/lib/liquid/expression.rb +28 -32
  12. data/lib/liquid/extensions.rb +2 -0
  13. data/lib/liquid/file_system.rb +6 -4
  14. data/lib/liquid/forloop_drop.rb +54 -4
  15. data/lib/liquid/i18n.rb +5 -3
  16. data/lib/liquid/interrupts.rb +3 -1
  17. data/lib/liquid/lexer.rb +30 -23
  18. data/lib/liquid/locales/en.yml +8 -5
  19. data/lib/liquid/parse_context.rb +20 -4
  20. data/lib/liquid/parse_tree_visitor.rb +2 -2
  21. data/lib/liquid/parser.rb +30 -18
  22. data/lib/liquid/parser_switching.rb +17 -3
  23. data/lib/liquid/partial_cache.rb +24 -0
  24. data/lib/liquid/profiler/hooks.rb +26 -14
  25. data/lib/liquid/profiler.rb +67 -86
  26. data/lib/liquid/range_lookup.rb +13 -3
  27. data/lib/liquid/registers.rb +51 -0
  28. data/lib/liquid/resource_limits.rb +47 -8
  29. data/lib/liquid/standardfilters.rb +551 -114
  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 +64 -5
  33. data/lib/liquid/tag/disableable.rb +22 -0
  34. data/lib/liquid/tag/disabler.rb +21 -0
  35. data/lib/liquid/tag.rb +28 -6
  36. data/lib/liquid/tags/assign.rb +36 -18
  37. data/lib/liquid/tags/break.rb +16 -3
  38. data/lib/liquid/tags/capture.rb +24 -18
  39. data/lib/liquid/tags/case.rb +61 -27
  40. data/lib/liquid/tags/comment.rb +18 -3
  41. data/lib/liquid/tags/continue.rb +16 -12
  42. data/lib/liquid/tags/cycle.rb +37 -25
  43. data/lib/liquid/tags/decrement.rb +22 -20
  44. data/lib/liquid/tags/echo.rb +41 -0
  45. data/lib/liquid/tags/for.rb +90 -87
  46. data/lib/liquid/tags/if.rb +50 -32
  47. data/lib/liquid/tags/ifchanged.rb +11 -10
  48. data/lib/liquid/tags/include.rb +49 -60
  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 +25 -11
  52. data/lib/liquid/tags/render.rb +109 -0
  53. data/lib/liquid/tags/table_row.rb +45 -19
  54. data/lib/liquid/tags/unless.rb +38 -19
  55. data/lib/liquid/template.rb +52 -72
  56. data/lib/liquid/template_factory.rb +9 -0
  57. data/lib/liquid/tokenizer.rb +18 -10
  58. data/lib/liquid/usage.rb +8 -0
  59. data/lib/liquid/utils.rb +13 -3
  60. data/lib/liquid/variable.rb +49 -44
  61. data/lib/liquid/variable_lookup.rb +18 -10
  62. data/lib/liquid/version.rb +2 -1
  63. data/lib/liquid.rb +18 -6
  64. metadata +20 -108
  65. data/lib/liquid/strainer.rb +0 -66
  66. data/lib/liquid/truffle.rb +0 -5
  67. data/test/fixtures/en_locale.yml +0 -9
  68. data/test/integration/assign_test.rb +0 -48
  69. data/test/integration/blank_test.rb +0 -106
  70. data/test/integration/block_test.rb +0 -12
  71. data/test/integration/capture_test.rb +0 -50
  72. data/test/integration/context_test.rb +0 -32
  73. data/test/integration/document_test.rb +0 -19
  74. data/test/integration/drop_test.rb +0 -273
  75. data/test/integration/error_handling_test.rb +0 -260
  76. data/test/integration/filter_test.rb +0 -178
  77. data/test/integration/hash_ordering_test.rb +0 -23
  78. data/test/integration/output_test.rb +0 -123
  79. data/test/integration/parse_tree_visitor_test.rb +0 -247
  80. data/test/integration/parsing_quirks_test.rb +0 -122
  81. data/test/integration/render_profiling_test.rb +0 -154
  82. data/test/integration/security_test.rb +0 -80
  83. data/test/integration/standard_filter_test.rb +0 -776
  84. data/test/integration/tags/break_tag_test.rb +0 -15
  85. data/test/integration/tags/continue_tag_test.rb +0 -15
  86. data/test/integration/tags/for_tag_test.rb +0 -410
  87. data/test/integration/tags/if_else_tag_test.rb +0 -188
  88. data/test/integration/tags/include_tag_test.rb +0 -253
  89. data/test/integration/tags/increment_tag_test.rb +0 -23
  90. data/test/integration/tags/raw_tag_test.rb +0 -31
  91. data/test/integration/tags/standard_tag_test.rb +0 -296
  92. data/test/integration/tags/statements_test.rb +0 -111
  93. data/test/integration/tags/table_row_test.rb +0 -64
  94. data/test/integration/tags/unless_else_tag_test.rb +0 -26
  95. data/test/integration/template_test.rb +0 -332
  96. data/test/integration/trim_mode_test.rb +0 -529
  97. data/test/integration/variable_test.rb +0 -96
  98. data/test/test_helper.rb +0 -116
  99. data/test/truffle/truffle_test.rb +0 -9
  100. data/test/unit/block_unit_test.rb +0 -58
  101. data/test/unit/condition_unit_test.rb +0 -166
  102. data/test/unit/context_unit_test.rb +0 -489
  103. data/test/unit/file_system_unit_test.rb +0 -35
  104. data/test/unit/i18n_unit_test.rb +0 -37
  105. data/test/unit/lexer_unit_test.rb +0 -51
  106. data/test/unit/parser_unit_test.rb +0 -82
  107. data/test/unit/regexp_unit_test.rb +0 -44
  108. data/test/unit/strainer_unit_test.rb +0 -164
  109. data/test/unit/tag_unit_test.rb +0 -21
  110. data/test/unit/tags/case_tag_unit_test.rb +0 -10
  111. data/test/unit/tags/for_tag_unit_test.rb +0 -13
  112. data/test/unit/tags/if_tag_unit_test.rb +0 -8
  113. data/test/unit/template_unit_test.rb +0 -78
  114. data/test/unit/tokenizer_unit_test.rb +0 -55
  115. data/test/unit/variable_unit_test.rb +0 -162
@@ -1,489 +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 test_variables
74
- @context['string'] = 'string'
75
- assert_equal 'string', @context['string']
76
-
77
- @context['num'] = 5
78
- assert_equal 5, @context['num']
79
-
80
- @context['time'] = Time.parse('2006-06-06 12:00:00')
81
- assert_equal Time.parse('2006-06-06 12:00:00'), @context['time']
82
-
83
- @context['date'] = Date.today
84
- assert_equal Date.today, @context['date']
85
-
86
- now = DateTime.now
87
- @context['datetime'] = now
88
- assert_equal now, @context['datetime']
89
-
90
- @context['bool'] = true
91
- assert_equal true, @context['bool']
92
-
93
- @context['bool'] = false
94
- assert_equal false, @context['bool']
95
-
96
- @context['nil'] = nil
97
- assert_nil @context['nil']
98
- assert_nil @context['nil']
99
- end
100
-
101
- def test_variables_not_existing
102
- assert_nil @context['does_not_exist']
103
- end
104
-
105
- def test_scoping
106
- @context.push
107
- @context.pop
108
-
109
- assert_raises(Liquid::ContextError) do
110
- @context.pop
111
- end
112
-
113
- assert_raises(Liquid::ContextError) do
114
- @context.push
115
- @context.pop
116
- @context.pop
117
- end
118
- end
119
-
120
- def test_length_query
121
- @context['numbers'] = [1, 2, 3, 4]
122
-
123
- assert_equal 4, @context['numbers.size']
124
-
125
- @context['numbers'] = { 1 => 1, 2 => 2, 3 => 3, 4 => 4 }
126
-
127
- assert_equal 4, @context['numbers.size']
128
-
129
- @context['numbers'] = { 1 => 1, 2 => 2, 3 => 3, 4 => 4, 'size' => 1000 }
130
-
131
- assert_equal 1000, @context['numbers.size']
132
- end
133
-
134
- def test_hyphenated_variable
135
- @context['oh-my'] = 'godz'
136
- assert_equal 'godz', @context['oh-my']
137
- end
138
-
139
- def test_add_filter
140
- filter = Module.new do
141
- def hi(output)
142
- output + ' hi!'
143
- end
144
- end
145
-
146
- context = Context.new
147
- context.add_filters(filter)
148
- assert_equal 'hi? hi!', context.invoke(:hi, 'hi?')
149
-
150
- context = Context.new
151
- assert_equal 'hi?', context.invoke(:hi, 'hi?')
152
-
153
- context.add_filters(filter)
154
- assert_equal 'hi? hi!', context.invoke(:hi, 'hi?')
155
- end
156
-
157
- def test_only_intended_filters_make_it_there
158
- filter = Module.new do
159
- def hi(output)
160
- output + ' hi!'
161
- end
162
- end
163
-
164
- context = Context.new
165
- assert_equal "Wookie", context.invoke("hi", "Wookie")
166
-
167
- context.add_filters(filter)
168
- assert_equal "Wookie hi!", context.invoke("hi", "Wookie")
169
- end
170
-
171
- def test_add_item_in_outer_scope
172
- @context['test'] = 'test'
173
- @context.push
174
- assert_equal 'test', @context['test']
175
- @context.pop
176
- assert_equal 'test', @context['test']
177
- end
178
-
179
- def test_add_item_in_inner_scope
180
- @context.push
181
- @context['test'] = 'test'
182
- assert_equal 'test', @context['test']
183
- @context.pop
184
- assert_nil @context['test']
185
- end
186
-
187
- def test_hierachical_data
188
- @context['hash'] = { "name" => 'tobi' }
189
- assert_equal 'tobi', @context['hash.name']
190
- assert_equal 'tobi', @context['hash["name"]']
191
- end
192
-
193
- def test_keywords
194
- assert_equal true, @context['true']
195
- assert_equal false, @context['false']
196
- end
197
-
198
- def test_digits
199
- assert_equal 100, @context['100']
200
- assert_equal 100.00, @context['100.00']
201
- end
202
-
203
- def test_strings
204
- assert_equal "hello!", @context['"hello!"']
205
- assert_equal "hello!", @context["'hello!'"]
206
- end
207
-
208
- def test_merge
209
- @context.merge({ "test" => "test" })
210
- assert_equal 'test', @context['test']
211
- @context.merge({ "test" => "newvalue", "foo" => "bar" })
212
- assert_equal 'newvalue', @context['test']
213
- assert_equal 'bar', @context['foo']
214
- end
215
-
216
- def test_array_notation
217
- @context['test'] = [1, 2, 3, 4, 5]
218
-
219
- assert_equal 1, @context['test[0]']
220
- assert_equal 2, @context['test[1]']
221
- assert_equal 3, @context['test[2]']
222
- assert_equal 4, @context['test[3]']
223
- assert_equal 5, @context['test[4]']
224
- end
225
-
226
- def test_recoursive_array_notation
227
- @context['test'] = { 'test' => [1, 2, 3, 4, 5] }
228
-
229
- assert_equal 1, @context['test.test[0]']
230
-
231
- @context['test'] = [{ 'test' => 'worked' }]
232
-
233
- assert_equal 'worked', @context['test[0].test']
234
- end
235
-
236
- def test_hash_to_array_transition
237
- @context['colors'] = {
238
- 'Blue' => ['003366', '336699', '6699CC', '99CCFF'],
239
- 'Green' => ['003300', '336633', '669966', '99CC99'],
240
- 'Yellow' => ['CC9900', 'FFCC00', 'FFFF99', 'FFFFCC'],
241
- 'Red' => ['660000', '993333', 'CC6666', 'FF9999']
242
- }
243
-
244
- assert_equal '003366', @context['colors.Blue[0]']
245
- assert_equal 'FF9999', @context['colors.Red[3]']
246
- end
247
-
248
- def test_try_first
249
- @context['test'] = [1, 2, 3, 4, 5]
250
-
251
- assert_equal 1, @context['test.first']
252
- assert_equal 5, @context['test.last']
253
-
254
- @context['test'] = { 'test' => [1, 2, 3, 4, 5] }
255
-
256
- assert_equal 1, @context['test.test.first']
257
- assert_equal 5, @context['test.test.last']
258
-
259
- @context['test'] = [1]
260
- assert_equal 1, @context['test.first']
261
- assert_equal 1, @context['test.last']
262
- end
263
-
264
- def test_access_hashes_with_hash_notation
265
- @context['products'] = { 'count' => 5, 'tags' => ['deepsnow', 'freestyle'] }
266
- @context['product'] = { 'variants' => [ { 'title' => 'draft151cm' }, { 'title' => 'element151cm' } ] }
267
-
268
- assert_equal 5, @context['products["count"]']
269
- assert_equal 'deepsnow', @context['products["tags"][0]']
270
- assert_equal 'deepsnow', @context['products["tags"].first']
271
- assert_equal 'draft151cm', @context['product["variants"][0]["title"]']
272
- assert_equal 'element151cm', @context['product["variants"][1]["title"]']
273
- assert_equal 'draft151cm', @context['product["variants"][0]["title"]']
274
- assert_equal 'element151cm', @context['product["variants"].last["title"]']
275
- end
276
-
277
- def test_access_variable_with_hash_notation
278
- @context['foo'] = 'baz'
279
- @context['bar'] = 'foo'
280
-
281
- assert_equal 'baz', @context['["foo"]']
282
- assert_equal 'baz', @context['[bar]']
283
- end
284
-
285
- def test_access_hashes_with_hash_access_variables
286
- @context['var'] = 'tags'
287
- @context['nested'] = { 'var' => 'tags' }
288
- @context['products'] = { 'count' => 5, 'tags' => ['deepsnow', 'freestyle'] }
289
-
290
- assert_equal 'deepsnow', @context['products[var].first']
291
- assert_equal 'freestyle', @context['products[nested.var].last']
292
- end
293
-
294
- def test_hash_notation_only_for_hash_access
295
- @context['array'] = [1, 2, 3, 4, 5]
296
- @context['hash'] = { 'first' => 'Hello' }
297
-
298
- assert_equal 1, @context['array.first']
299
- assert_nil @context['array["first"]']
300
- assert_equal 'Hello', @context['hash["first"]']
301
- end
302
-
303
- def test_first_can_appear_in_middle_of_callchain
304
- @context['product'] = { 'variants' => [ { 'title' => 'draft151cm' }, { 'title' => 'element151cm' } ] }
305
-
306
- assert_equal 'draft151cm', @context['product.variants[0].title']
307
- assert_equal 'element151cm', @context['product.variants[1].title']
308
- assert_equal 'draft151cm', @context['product.variants.first.title']
309
- assert_equal 'element151cm', @context['product.variants.last.title']
310
- end
311
-
312
- def test_cents
313
- @context.merge("cents" => HundredCentes.new)
314
- assert_equal 100, @context['cents']
315
- end
316
-
317
- def test_nested_cents
318
- @context.merge("cents" => { 'amount' => HundredCentes.new })
319
- assert_equal 100, @context['cents.amount']
320
-
321
- @context.merge("cents" => { 'cents' => { 'amount' => HundredCentes.new } })
322
- assert_equal 100, @context['cents.cents.amount']
323
- end
324
-
325
- def test_cents_through_drop
326
- @context.merge("cents" => CentsDrop.new)
327
- assert_equal 100, @context['cents.amount']
328
- end
329
-
330
- def test_nested_cents_through_drop
331
- @context.merge("vars" => { "cents" => CentsDrop.new })
332
- assert_equal 100, @context['vars.cents.amount']
333
- end
334
-
335
- def test_drop_methods_with_question_marks
336
- @context.merge("cents" => CentsDrop.new)
337
- assert @context['cents.non_zero?']
338
- end
339
-
340
- def test_context_from_within_drop
341
- @context.merge("test" => '123', "vars" => ContextSensitiveDrop.new)
342
- assert_equal '123', @context['vars.test']
343
- end
344
-
345
- def test_nested_context_from_within_drop
346
- @context.merge("test" => '123', "vars" => { "local" => ContextSensitiveDrop.new })
347
- assert_equal '123', @context['vars.local.test']
348
- end
349
-
350
- def test_ranges
351
- @context.merge("test" => '5')
352
- assert_equal (1..5), @context['(1..5)']
353
- assert_equal (1..5), @context['(1..test)']
354
- assert_equal (5..5), @context['(test..test)']
355
- end
356
-
357
- def test_cents_through_drop_nestedly
358
- @context.merge("cents" => { "cents" => CentsDrop.new })
359
- assert_equal 100, @context['cents.cents.amount']
360
-
361
- @context.merge("cents" => { "cents" => { "cents" => CentsDrop.new } })
362
- assert_equal 100, @context['cents.cents.cents.amount']
363
- end
364
-
365
- def test_drop_with_variable_called_only_once
366
- @context['counter'] = CounterDrop.new
367
-
368
- assert_equal 1, @context['counter.count']
369
- assert_equal 2, @context['counter.count']
370
- assert_equal 3, @context['counter.count']
371
- end
372
-
373
- def test_drop_with_key_called_only_once
374
- @context['counter'] = CounterDrop.new
375
-
376
- assert_equal 1, @context['counter["count"]']
377
- assert_equal 2, @context['counter["count"]']
378
- assert_equal 3, @context['counter["count"]']
379
- end
380
-
381
- def test_proc_as_variable
382
- @context['dynamic'] = proc { 'Hello' }
383
-
384
- assert_equal 'Hello', @context['dynamic']
385
- end
386
-
387
- def test_lambda_as_variable
388
- @context['dynamic'] = proc { 'Hello' }
389
-
390
- assert_equal 'Hello', @context['dynamic']
391
- end
392
-
393
- def test_nested_lambda_as_variable
394
- @context['dynamic'] = { "lambda" => proc { 'Hello' } }
395
-
396
- assert_equal 'Hello', @context['dynamic.lambda']
397
- end
398
-
399
- def test_array_containing_lambda_as_variable
400
- @context['dynamic'] = [1, 2, proc { 'Hello' }, 4, 5]
401
-
402
- assert_equal 'Hello', @context['dynamic[2]']
403
- end
404
-
405
- def test_lambda_is_called_once
406
- @context['callcount'] = proc { @global ||= 0; @global += 1; @global.to_s }
407
-
408
- assert_equal '1', @context['callcount']
409
- assert_equal '1', @context['callcount']
410
- assert_equal '1', @context['callcount']
411
-
412
- @global = nil
413
- end
414
-
415
- def test_nested_lambda_is_called_once
416
- @context['callcount'] = { "lambda" => proc { @global ||= 0; @global += 1; @global.to_s } }
417
-
418
- assert_equal '1', @context['callcount.lambda']
419
- assert_equal '1', @context['callcount.lambda']
420
- assert_equal '1', @context['callcount.lambda']
421
-
422
- @global = nil
423
- end
424
-
425
- def test_lambda_in_array_is_called_once
426
- @context['callcount'] = [1, 2, proc { @global ||= 0; @global += 1; @global.to_s }, 4, 5]
427
-
428
- assert_equal '1', @context['callcount[2]']
429
- assert_equal '1', @context['callcount[2]']
430
- assert_equal '1', @context['callcount[2]']
431
-
432
- @global = nil
433
- end
434
-
435
- def test_access_to_context_from_proc
436
- @context.registers[:magic] = 345392
437
-
438
- @context['magic'] = proc { @context.registers[:magic] }
439
-
440
- assert_equal 345392, @context['magic']
441
- end
442
-
443
- def test_to_liquid_and_context_at_first_level
444
- @context['category'] = Category.new("foobar")
445
- assert_kind_of CategoryDrop, @context['category']
446
- assert_equal @context, @context['category'].context
447
- end
448
-
449
- def test_interrupt_avoids_object_allocations
450
- assert_no_object_allocations do
451
- @context.interrupt?
452
- end
453
- end
454
-
455
- def test_context_initialization_with_a_proc_in_environment
456
- contx = Context.new([test: ->(c) { c['poutine'] }], { test: :foo })
457
-
458
- assert contx
459
- assert_nil contx['poutine']
460
- end
461
-
462
- def test_apply_global_filter
463
- global_filter_proc = ->(output) { "#{output} filtered" }
464
-
465
- context = Context.new
466
- context.global_filter = global_filter_proc
467
-
468
- assert_equal 'hi filtered', context.apply_global_filter('hi')
469
- end
470
-
471
- def test_apply_global_filter_when_no_global_filter_exist
472
- context = Context.new
473
- assert_equal 'hi', context.apply_global_filter('hi')
474
- end
475
-
476
- private
477
-
478
- def assert_no_object_allocations
479
- unless RUBY_ENGINE == 'ruby'
480
- skip "stackprof needed to count object allocations"
481
- end
482
- require 'stackprof'
483
-
484
- profile = StackProf.run(mode: :object) do
485
- yield
486
- end
487
- assert_equal 0, profile[:samples]
488
- end
489
- 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