liquid 4.0.3 → 5.0.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 (125) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +33 -0
  3. data/README.md +6 -0
  4. data/lib/liquid.rb +17 -5
  5. data/lib/liquid/block.rb +31 -14
  6. data/lib/liquid/block_body.rb +164 -54
  7. data/lib/liquid/condition.rb +39 -18
  8. data/lib/liquid/context.rb +106 -51
  9. data/lib/liquid/document.rb +47 -9
  10. data/lib/liquid/drop.rb +4 -2
  11. data/lib/liquid/errors.rb +20 -18
  12. data/lib/liquid/expression.rb +29 -34
  13. data/lib/liquid/extensions.rb +2 -0
  14. data/lib/liquid/file_system.rb +6 -4
  15. data/lib/liquid/forloop_drop.rb +11 -4
  16. data/lib/liquid/i18n.rb +5 -3
  17. data/lib/liquid/interrupts.rb +3 -1
  18. data/lib/liquid/lexer.rb +30 -23
  19. data/lib/liquid/locales/en.yml +3 -1
  20. data/lib/liquid/parse_context.rb +16 -4
  21. data/lib/liquid/parse_tree_visitor.rb +2 -2
  22. data/lib/liquid/parser.rb +30 -18
  23. data/lib/liquid/parser_switching.rb +17 -3
  24. data/lib/liquid/partial_cache.rb +24 -0
  25. data/lib/liquid/profiler.rb +67 -86
  26. data/lib/liquid/profiler/hooks.rb +26 -14
  27. data/lib/liquid/range_lookup.rb +5 -3
  28. data/lib/liquid/register.rb +6 -0
  29. data/lib/liquid/resource_limits.rb +47 -8
  30. data/lib/liquid/standardfilters.rb +63 -44
  31. data/lib/liquid/static_registers.rb +44 -0
  32. data/lib/liquid/strainer_factory.rb +36 -0
  33. data/lib/liquid/strainer_template.rb +53 -0
  34. data/lib/liquid/tablerowloop_drop.rb +6 -4
  35. data/lib/liquid/tag.rb +28 -6
  36. data/lib/liquid/tag/disableable.rb +22 -0
  37. data/lib/liquid/tag/disabler.rb +21 -0
  38. data/lib/liquid/tags/assign.rb +24 -10
  39. data/lib/liquid/tags/break.rb +8 -3
  40. data/lib/liquid/tags/capture.rb +11 -8
  41. data/lib/liquid/tags/case.rb +33 -27
  42. data/lib/liquid/tags/comment.rb +5 -3
  43. data/lib/liquid/tags/continue.rb +8 -3
  44. data/lib/liquid/tags/cycle.rb +25 -14
  45. data/lib/liquid/tags/decrement.rb +6 -3
  46. data/lib/liquid/tags/echo.rb +26 -0
  47. data/lib/liquid/tags/for.rb +68 -44
  48. data/lib/liquid/tags/if.rb +35 -23
  49. data/lib/liquid/tags/ifchanged.rb +11 -10
  50. data/lib/liquid/tags/include.rb +34 -47
  51. data/lib/liquid/tags/increment.rb +7 -3
  52. data/lib/liquid/tags/raw.rb +14 -11
  53. data/lib/liquid/tags/render.rb +84 -0
  54. data/lib/liquid/tags/table_row.rb +23 -19
  55. data/lib/liquid/tags/unless.rb +15 -15
  56. data/lib/liquid/template.rb +55 -71
  57. data/lib/liquid/template_factory.rb +9 -0
  58. data/lib/liquid/tokenizer.rb +17 -9
  59. data/lib/liquid/usage.rb +8 -0
  60. data/lib/liquid/utils.rb +5 -3
  61. data/lib/liquid/variable.rb +46 -41
  62. data/lib/liquid/variable_lookup.rb +8 -6
  63. data/lib/liquid/version.rb +2 -1
  64. data/test/integration/assign_test.rb +74 -5
  65. data/test/integration/blank_test.rb +11 -8
  66. data/test/integration/block_test.rb +47 -1
  67. data/test/integration/capture_test.rb +18 -10
  68. data/test/integration/context_test.rb +608 -5
  69. data/test/integration/document_test.rb +4 -2
  70. data/test/integration/drop_test.rb +67 -83
  71. data/test/integration/error_handling_test.rb +73 -61
  72. data/test/integration/expression_test.rb +46 -0
  73. data/test/integration/filter_test.rb +53 -42
  74. data/test/integration/hash_ordering_test.rb +5 -3
  75. data/test/integration/output_test.rb +26 -24
  76. data/test/integration/parsing_quirks_test.rb +19 -7
  77. data/test/integration/{render_profiling_test.rb → profiler_test.rb} +84 -25
  78. data/test/integration/security_test.rb +30 -21
  79. data/test/integration/standard_filter_test.rb +339 -281
  80. data/test/integration/tag/disableable_test.rb +59 -0
  81. data/test/integration/tag_test.rb +45 -0
  82. data/test/integration/tags/break_tag_test.rb +4 -2
  83. data/test/integration/tags/continue_tag_test.rb +4 -2
  84. data/test/integration/tags/echo_test.rb +13 -0
  85. data/test/integration/tags/for_tag_test.rb +107 -51
  86. data/test/integration/tags/if_else_tag_test.rb +5 -3
  87. data/test/integration/tags/include_tag_test.rb +70 -54
  88. data/test/integration/tags/increment_tag_test.rb +4 -2
  89. data/test/integration/tags/liquid_tag_test.rb +116 -0
  90. data/test/integration/tags/raw_tag_test.rb +14 -11
  91. data/test/integration/tags/render_tag_test.rb +213 -0
  92. data/test/integration/tags/standard_tag_test.rb +38 -31
  93. data/test/integration/tags/statements_test.rb +23 -21
  94. data/test/integration/tags/table_row_test.rb +2 -0
  95. data/test/integration/tags/unless_else_tag_test.rb +4 -2
  96. data/test/integration/template_test.rb +118 -124
  97. data/test/integration/trim_mode_test.rb +78 -44
  98. data/test/integration/variable_test.rb +43 -32
  99. data/test/test_helper.rb +75 -22
  100. data/test/unit/block_unit_test.rb +19 -24
  101. data/test/unit/condition_unit_test.rb +79 -77
  102. data/test/unit/file_system_unit_test.rb +6 -4
  103. data/test/unit/i18n_unit_test.rb +7 -5
  104. data/test/unit/lexer_unit_test.rb +11 -9
  105. data/test/{integration → unit}/parse_tree_visitor_test.rb +2 -2
  106. data/test/unit/parser_unit_test.rb +37 -35
  107. data/test/unit/partial_cache_unit_test.rb +128 -0
  108. data/test/unit/regexp_unit_test.rb +17 -15
  109. data/test/unit/static_registers_unit_test.rb +156 -0
  110. data/test/unit/strainer_factory_unit_test.rb +100 -0
  111. data/test/unit/strainer_template_unit_test.rb +82 -0
  112. data/test/unit/tag_unit_test.rb +5 -3
  113. data/test/unit/tags/case_tag_unit_test.rb +3 -1
  114. data/test/unit/tags/for_tag_unit_test.rb +4 -2
  115. data/test/unit/tags/if_tag_unit_test.rb +3 -1
  116. data/test/unit/template_factory_unit_test.rb +12 -0
  117. data/test/unit/template_unit_test.rb +19 -10
  118. data/test/unit/tokenizer_unit_test.rb +19 -17
  119. data/test/unit/variable_unit_test.rb +51 -49
  120. metadata +73 -47
  121. data/lib/liquid/strainer.rb +0 -66
  122. data/lib/liquid/truffle.rb +0 -5
  123. data/test/truffle/truffle_test.rb +0 -9
  124. data/test/unit/context_unit_test.rb +0 -489
  125. data/test/unit/strainer_unit_test.rb +0 -164
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class ExpressionTest < Minitest::Test
6
+ def test_keyword_literals
7
+ assert_equal(true, parse_and_eval("true"))
8
+ assert_equal(true, parse_and_eval(" true "))
9
+ end
10
+
11
+ def test_string
12
+ assert_equal("single quoted", parse_and_eval("'single quoted'"))
13
+ assert_equal("double quoted", parse_and_eval('"double quoted"'))
14
+ assert_equal("spaced", parse_and_eval(" 'spaced' "))
15
+ assert_equal("spaced2", parse_and_eval(' "spaced2" '))
16
+ end
17
+
18
+ def test_int
19
+ assert_equal(123, parse_and_eval("123"))
20
+ assert_equal(456, parse_and_eval(" 456 "))
21
+ assert_equal(12, parse_and_eval("012"))
22
+ end
23
+
24
+ def test_float
25
+ assert_equal(1.5, parse_and_eval("1.5"))
26
+ assert_equal(2.5, parse_and_eval(" 2.5 "))
27
+ end
28
+
29
+ def test_range
30
+ assert_equal(1..2, parse_and_eval("(1..2)"))
31
+ assert_equal(3..4, parse_and_eval(" ( 3 .. 4 ) "))
32
+ end
33
+
34
+ private
35
+
36
+ def parse_and_eval(markup, **assigns)
37
+ if Liquid::Template.error_mode == :strict
38
+ p = Liquid::Parser.new(markup)
39
+ markup = p.expression
40
+ p.consume(:end_of_string)
41
+ end
42
+ expression = Liquid::Expression.parse(markup)
43
+ context = Liquid::Context.new(assigns)
44
+ context.evaluate(expression)
45
+ end
46
+ end
@@ -1,24 +1,26 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  module MoneyFilter
4
6
  def money(input)
5
- sprintf(' %d$ ', input)
7
+ format(' %d$ ', input)
6
8
  end
7
9
 
8
10
  def money_with_underscore(input)
9
- sprintf(' %d$ ', input)
11
+ format(' %d$ ', input)
10
12
  end
11
13
  end
12
14
 
13
15
  module CanadianMoneyFilter
14
16
  def money(input)
15
- sprintf(' %d$ CAD ', input)
17
+ format(' %d$ CAD ', input)
16
18
  end
17
19
  end
18
20
 
19
21
  module SubstituteFilter
20
22
  def substitute(input, params = {})
21
- input.gsub(/%\{(\w+)\}/) { |match| params[$1] }
23
+ input.gsub(/%\{(\w+)\}/) { |_match| params[Regexp.last_match(1)] }
22
24
  end
23
25
  end
24
26
 
@@ -26,7 +28,7 @@ class FiltersTest < Minitest::Test
26
28
  include Liquid
27
29
 
28
30
  module OverrideObjectMethodFilter
29
- def tap(input)
31
+ def tap(_input)
30
32
  "tap overridden"
31
33
  end
32
34
  end
@@ -39,13 +41,13 @@ class FiltersTest < Minitest::Test
39
41
  @context['var'] = 1000
40
42
  @context.add_filters(MoneyFilter)
41
43
 
42
- assert_equal ' 1000$ ', Template.parse("{{var | money}}").render(@context)
44
+ assert_equal(' 1000$ ', Template.parse("{{var | money}}").render(@context))
43
45
  end
44
46
 
45
47
  def test_underscore_in_filter_name
46
48
  @context['var'] = 1000
47
49
  @context.add_filters(MoneyFilter)
48
- assert_equal ' 1000$ ', Template.parse("{{var | money_with_underscore}}").render(@context)
50
+ assert_equal(' 1000$ ', Template.parse("{{var | money_with_underscore}}").render(@context))
49
51
  end
50
52
 
51
53
  def test_second_filter_overwrites_first
@@ -53,103 +55,112 @@ class FiltersTest < Minitest::Test
53
55
  @context.add_filters(MoneyFilter)
54
56
  @context.add_filters(CanadianMoneyFilter)
55
57
 
56
- assert_equal ' 1000$ CAD ', Template.parse("{{var | money}}").render(@context)
58
+ assert_equal(' 1000$ CAD ', Template.parse("{{var | money}}").render(@context))
57
59
  end
58
60
 
59
61
  def test_size
60
62
  @context['var'] = 'abcd'
61
63
  @context.add_filters(MoneyFilter)
62
64
 
63
- assert_equal '4', Template.parse("{{var | size}}").render(@context)
65
+ assert_equal('4', Template.parse("{{var | size}}").render(@context))
64
66
  end
65
67
 
66
68
  def test_join
67
69
  @context['var'] = [1, 2, 3, 4]
68
70
 
69
- assert_equal "1 2 3 4", Template.parse("{{var | join}}").render(@context)
71
+ assert_equal("1 2 3 4", Template.parse("{{var | join}}").render(@context))
70
72
  end
71
73
 
72
74
  def test_sort
73
- @context['value'] = 3
75
+ @context['value'] = 3
74
76
  @context['numbers'] = [2, 1, 4, 3]
75
- @context['words'] = ['expected', 'as', 'alphabetic']
76
- @context['arrays'] = ['flower', 'are']
77
+ @context['words'] = ['expected', 'as', 'alphabetic']
78
+ @context['arrays'] = ['flower', 'are']
77
79
  @context['case_sensitive'] = ['sensitive', 'Expected', 'case']
78
80
 
79
- assert_equal '1 2 3 4', Template.parse("{{numbers | sort | join}}").render(@context)
80
- assert_equal 'alphabetic as expected', Template.parse("{{words | sort | join}}").render(@context)
81
- assert_equal '3', Template.parse("{{value | sort}}").render(@context)
82
- assert_equal 'are flower', Template.parse("{{arrays | sort | join}}").render(@context)
83
- assert_equal 'Expected case sensitive', Template.parse("{{case_sensitive | sort | join}}").render(@context)
81
+ assert_equal('1 2 3 4', Template.parse("{{numbers | sort | join}}").render(@context))
82
+ assert_equal('alphabetic as expected', Template.parse("{{words | sort | join}}").render(@context))
83
+ assert_equal('3', Template.parse("{{value | sort}}").render(@context))
84
+ assert_equal('are flower', Template.parse("{{arrays | sort | join}}").render(@context))
85
+ assert_equal('Expected case sensitive', Template.parse("{{case_sensitive | sort | join}}").render(@context))
84
86
  end
85
87
 
86
88
  def test_sort_natural
87
- @context['words'] = ['case', 'Assert', 'Insensitive']
88
- @context['hashes'] = [{ 'a' => 'A' }, { 'a' => 'b' }, { 'a' => 'C' }]
89
+ @context['words'] = ['case', 'Assert', 'Insensitive']
90
+ @context['hashes'] = [{ 'a' => 'A' }, { 'a' => 'b' }, { 'a' => 'C' }]
89
91
  @context['objects'] = [TestObject.new('A'), TestObject.new('b'), TestObject.new('C')]
90
92
 
91
93
  # Test strings
92
- assert_equal 'Assert case Insensitive', Template.parse("{{words | sort_natural | join}}").render(@context)
94
+ assert_equal('Assert case Insensitive', Template.parse("{{words | sort_natural | join}}").render(@context))
93
95
 
94
96
  # Test hashes
95
- assert_equal 'A b C', Template.parse("{{hashes | sort_natural: 'a' | map: 'a' | join}}").render(@context)
97
+ assert_equal('A b C', Template.parse("{{hashes | sort_natural: 'a' | map: 'a' | join}}").render(@context))
96
98
 
97
99
  # Test objects
98
- assert_equal 'A b C', Template.parse("{{objects | sort_natural: 'a' | map: 'a' | join}}").render(@context)
100
+ assert_equal('A b C', Template.parse("{{objects | sort_natural: 'a' | map: 'a' | join}}").render(@context))
99
101
  end
100
102
 
101
103
  def test_compact
102
- @context['words'] = ['a', nil, 'b', nil, 'c']
103
- @context['hashes'] = [{ 'a' => 'A' }, { 'a' => nil }, { 'a' => 'C' }]
104
+ @context['words'] = ['a', nil, 'b', nil, 'c']
105
+ @context['hashes'] = [{ 'a' => 'A' }, { 'a' => nil }, { 'a' => 'C' }]
104
106
  @context['objects'] = [TestObject.new('A'), TestObject.new(nil), TestObject.new('C')]
105
107
 
106
108
  # Test strings
107
- assert_equal 'a b c', Template.parse("{{words | compact | join}}").render(@context)
109
+ assert_equal('a b c', Template.parse("{{words | compact | join}}").render(@context))
108
110
 
109
111
  # Test hashes
110
- assert_equal 'A C', Template.parse("{{hashes | compact: 'a' | map: 'a' | join}}").render(@context)
112
+ assert_equal('A C', Template.parse("{{hashes | compact: 'a' | map: 'a' | join}}").render(@context))
111
113
 
112
114
  # Test objects
113
- assert_equal 'A C', Template.parse("{{objects | compact: 'a' | map: 'a' | join}}").render(@context)
115
+ assert_equal('A C', Template.parse("{{objects | compact: 'a' | map: 'a' | join}}").render(@context))
114
116
  end
115
117
 
116
118
  def test_strip_html
117
119
  @context['var'] = "<b>bla blub</a>"
118
120
 
119
- assert_equal "bla blub", Template.parse("{{ var | strip_html }}").render(@context)
121
+ assert_equal("bla blub", Template.parse("{{ var | strip_html }}").render(@context))
120
122
  end
121
123
 
122
124
  def test_strip_html_ignore_comments_with_html
123
125
  @context['var'] = "<!-- split and some <ul> tag --><b>bla blub</a>"
124
126
 
125
- assert_equal "bla blub", Template.parse("{{ var | strip_html }}").render(@context)
127
+ assert_equal("bla blub", Template.parse("{{ var | strip_html }}").render(@context))
126
128
  end
127
129
 
128
130
  def test_capitalize
129
131
  @context['var'] = "blub"
130
132
 
131
- assert_equal "Blub", Template.parse("{{ var | capitalize }}").render(@context)
133
+ assert_equal("Blub", Template.parse("{{ var | capitalize }}").render(@context))
132
134
  end
133
135
 
134
136
  def test_nonexistent_filter_is_ignored
135
137
  @context['var'] = 1000
136
138
 
137
- assert_equal '1000', Template.parse("{{ var | xyzzy }}").render(@context)
139
+ assert_equal('1000', Template.parse("{{ var | xyzzy }}").render(@context))
138
140
  end
139
141
 
140
142
  def test_filter_with_keyword_arguments
141
143
  @context['surname'] = 'john'
142
- @context['input'] = 'hello %{first_name}, %{last_name}'
144
+ @context['input'] = 'hello %{first_name}, %{last_name}'
143
145
  @context.add_filters(SubstituteFilter)
144
- output = Template.parse(%({{ input | substitute: first_name: surname, last_name: 'doe' }})).render(@context)
145
- assert_equal 'hello john, doe', output
146
+ output = Template.parse(%({{ input | substitute: first_name: surname, last_name: 'doe' }})).render(@context)
147
+ assert_equal('hello john, doe', output)
146
148
  end
147
149
 
148
150
  def test_override_object_method_in_filter
149
- assert_equal "tap overridden", Template.parse("{{var | tap}}").render!({ 'var' => 1000 }, filters: [OverrideObjectMethodFilter])
151
+ assert_equal("tap overridden", Template.parse("{{var | tap}}").render!({ 'var' => 1000 }, filters: [OverrideObjectMethodFilter]))
150
152
 
151
153
  # tap still treated as a non-existent filter
152
- assert_equal "1000", Template.parse("{{var | tap}}").render!({ 'var' => 1000 })
154
+ assert_equal("1000", Template.parse("{{var | tap}}").render!('var' => 1000))
155
+ end
156
+
157
+ def test_liquid_argument_error
158
+ source = "{{ '' | size: 'too many args' }}"
159
+ exc = assert_raises(Liquid::ArgumentError) do
160
+ Template.parse(source).render!
161
+ end
162
+ assert_match(/\ALiquid error: wrong number of arguments /, exc.message)
163
+ assert_equal(exc.message, Template.parse(source).render)
153
164
  end
154
165
  end
155
166
 
@@ -158,15 +169,15 @@ class FiltersInTemplate < Minitest::Test
158
169
 
159
170
  def test_local_global
160
171
  with_global_filter(MoneyFilter) do
161
- assert_equal " 1000$ ", Template.parse("{{1000 | money}}").render!(nil, nil)
162
- assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render!(nil, filters: CanadianMoneyFilter)
163
- assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render!(nil, filters: [CanadianMoneyFilter])
172
+ assert_equal(" 1000$ ", Template.parse("{{1000 | money}}").render!(nil, nil))
173
+ assert_equal(" 1000$ CAD ", Template.parse("{{1000 | money}}").render!(nil, filters: CanadianMoneyFilter))
174
+ assert_equal(" 1000$ CAD ", Template.parse("{{1000 | money}}").render!(nil, filters: [CanadianMoneyFilter]))
164
175
  end
165
176
  end
166
177
 
167
178
  def test_local_filter_with_deprecated_syntax
168
- assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render!(nil, CanadianMoneyFilter)
169
- assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render!(nil, [CanadianMoneyFilter])
179
+ assert_equal(" 1000$ CAD ", Template.parse("{{1000 | money}}").render!(nil, CanadianMoneyFilter))
180
+ assert_equal(" 1000$ CAD ", Template.parse("{{1000 | money}}").render!(nil, [CanadianMoneyFilter]))
170
181
  end
171
182
  end # FiltersTest
172
183
 
@@ -1,15 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class HashOrderingTest < Minitest::Test
4
6
  module MoneyFilter
5
7
  def money(input)
6
- sprintf(' %d$ ', input)
8
+ format(' %d$ ', input)
7
9
  end
8
10
  end
9
11
 
10
12
  module CanadianMoneyFilter
11
13
  def money(input)
12
- sprintf(' %d$ CAD ', input)
14
+ format(' %d$ CAD ', input)
13
15
  end
14
16
  end
15
17
 
@@ -17,7 +19,7 @@ class HashOrderingTest < Minitest::Test
17
19
 
18
20
  def test_global_register_order
19
21
  with_global_filter(MoneyFilter, CanadianMoneyFilter) do
20
- assert_equal " 1000$ CAD ", Template.parse("{{1000 | money}}").render(nil, nil)
22
+ assert_equal(" 1000$ CAD ", Template.parse("{{1000 | money}}").render(nil, nil))
21
23
  end
22
24
  end
23
25
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  module FunnyFilter
4
- def make_funny(input)
6
+ def make_funny(_input)
5
7
  'LOL'
6
8
  end
7
9
 
@@ -32,7 +34,7 @@ class OutputTest < Minitest::Test
32
34
  def setup
33
35
  @assigns = {
34
36
  'best_cars' => 'bmw',
35
- 'car' => { 'bmw' => 'good', 'gm' => 'bad' }
37
+ 'car' => { 'bmw' => 'good', 'gm' => 'bad' },
36
38
  }
37
39
  end
38
40
 
@@ -40,84 +42,84 @@ class OutputTest < Minitest::Test
40
42
  text = %( {{best_cars}} )
41
43
 
42
44
  expected = %( bmw )
43
- assert_equal expected, Template.parse(text).render!(@assigns)
45
+ assert_equal(expected, Template.parse(text).render!(@assigns))
44
46
  end
45
47
 
46
48
  def test_variable_traversing_with_two_brackets
47
49
  text = %({{ site.data.menu[include.menu][include.locale] }})
48
- assert_equal "it works!", Template.parse(text).render!(
50
+ assert_equal("it works!", Template.parse(text).render!(
49
51
  "site" => { "data" => { "menu" => { "foo" => { "bar" => "it works!" } } } },
50
52
  "include" => { "menu" => "foo", "locale" => "bar" }
51
- )
53
+ ))
52
54
  end
53
55
 
54
56
  def test_variable_traversing
55
57
  text = %( {{car.bmw}} {{car.gm}} {{car.bmw}} )
56
58
 
57
59
  expected = %( good bad good )
58
- assert_equal expected, Template.parse(text).render!(@assigns)
60
+ assert_equal(expected, Template.parse(text).render!(@assigns))
59
61
  end
60
62
 
61
63
  def test_variable_piping
62
- text = %( {{ car.gm | make_funny }} )
64
+ text = %( {{ car.gm | make_funny }} )
63
65
  expected = %( LOL )
64
66
 
65
- assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
67
+ assert_equal(expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter]))
66
68
  end
67
69
 
68
70
  def test_variable_piping_with_input
69
- text = %( {{ car.gm | cite_funny }} )
71
+ text = %( {{ car.gm | cite_funny }} )
70
72
  expected = %( LOL: bad )
71
73
 
72
- assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
74
+ assert_equal(expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter]))
73
75
  end
74
76
 
75
77
  def test_variable_piping_with_args
76
- text = %! {{ car.gm | add_smiley : ':-(' }} !
78
+ text = %! {{ car.gm | add_smiley : ':-(' }} !
77
79
  expected = %| bad :-( |
78
80
 
79
- assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
81
+ assert_equal(expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter]))
80
82
  end
81
83
 
82
84
  def test_variable_piping_with_no_args
83
- text = %( {{ car.gm | add_smiley }} )
85
+ text = %( {{ car.gm | add_smiley }} )
84
86
  expected = %| bad :-) |
85
87
 
86
- assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
88
+ assert_equal(expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter]))
87
89
  end
88
90
 
89
91
  def test_multiple_variable_piping_with_args
90
- text = %! {{ car.gm | add_smiley : ':-(' | add_smiley : ':-('}} !
92
+ text = %! {{ car.gm | add_smiley : ':-(' | add_smiley : ':-('}} !
91
93
  expected = %| bad :-( :-( |
92
94
 
93
- assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
95
+ assert_equal(expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter]))
94
96
  end
95
97
 
96
98
  def test_variable_piping_with_multiple_args
97
- text = %( {{ car.gm | add_tag : 'span', 'bar'}} )
99
+ text = %( {{ car.gm | add_tag : 'span', 'bar'}} )
98
100
  expected = %( <span id="bar">bad</span> )
99
101
 
100
- assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
102
+ assert_equal(expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter]))
101
103
  end
102
104
 
103
105
  def test_variable_piping_with_variable_args
104
- text = %( {{ car.gm | add_tag : 'span', car.bmw}} )
106
+ text = %( {{ car.gm | add_tag : 'span', car.bmw}} )
105
107
  expected = %( <span id="good">bad</span> )
106
108
 
107
- assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
109
+ assert_equal(expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter]))
108
110
  end
109
111
 
110
112
  def test_multiple_pipings
111
- text = %( {{ best_cars | cite_funny | paragraph }} )
113
+ text = %( {{ best_cars | cite_funny | paragraph }} )
112
114
  expected = %( <p>LOL: bmw</p> )
113
115
 
114
- assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
116
+ assert_equal(expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter]))
115
117
  end
116
118
 
117
119
  def test_link_to
118
- text = %( {{ 'Typo' | link_to: 'http://typo.leetsoft.com' }} )
120
+ text = %( {{ 'Typo' | link_to: 'http://typo.leetsoft.com' }} )
119
121
  expected = %( <a href="http://typo.leetsoft.com">Typo</a> )
120
122
 
121
- assert_equal expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter])
123
+ assert_equal(expected, Template.parse(text).render!(@assigns, filters: [FunnyFilter]))
122
124
  end
123
125
  end # OutputTest
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class ParsingQuirksTest < Minitest::Test
@@ -5,7 +7,7 @@ class ParsingQuirksTest < Minitest::Test
5
7
 
6
8
  def test_parsing_css
7
9
  text = " div { font-weight: bold; } "
8
- assert_equal text, Template.parse(text).render!
10
+ assert_equal(text, Template.parse(text).render!)
9
11
  end
10
12
 
11
13
  def test_raise_on_single_close_bracet
@@ -27,10 +29,10 @@ class ParsingQuirksTest < Minitest::Test
27
29
  end
28
30
 
29
31
  def test_error_on_empty_filter
30
- assert Template.parse("{{test}}")
32
+ assert(Template.parse("{{test}}"))
31
33
 
32
34
  with_error_mode(:lax) do
33
- assert Template.parse("{{|test}}")
35
+ assert(Template.parse("{{|test}}"))
34
36
  end
35
37
 
36
38
  with_error_mode(:strict) do
@@ -62,15 +64,15 @@ class ParsingQuirksTest < Minitest::Test
62
64
  end
63
65
 
64
66
  def test_no_error_on_lax_empty_filter
65
- assert Template.parse("{{test |a|b|}}", error_mode: :lax)
66
- assert Template.parse("{{test}}", error_mode: :lax)
67
- assert Template.parse("{{|test|}}", error_mode: :lax)
67
+ assert(Template.parse("{{test |a|b|}}", error_mode: :lax))
68
+ assert(Template.parse("{{test}}", error_mode: :lax))
69
+ assert(Template.parse("{{|test|}}", error_mode: :lax))
68
70
  end
69
71
 
70
72
  def test_meaningless_parens_lax
71
73
  with_error_mode(:lax) do
72
74
  assigns = { 'b' => 'bar', 'c' => 'baz' }
73
- markup = "a == 'foo' or (b == 'bar' and c == 'baz') or false"
75
+ markup = "a == 'foo' or (b == 'bar' and c == 'baz') or false"
74
76
  assert_template_result(' YES ', "{% if #{markup} %} YES {% endif %}", assigns)
75
77
  end
76
78
  end
@@ -116,6 +118,16 @@ class ParsingQuirksTest < Minitest::Test
116
118
  end
117
119
  end
118
120
 
121
+ def test_blank_variable_markup
122
+ assert_template_result('', "{{}}")
123
+ end
124
+
125
+ def test_lookup_on_var_with_literal_name
126
+ assigns = { "blank" => { "x" => "result" } }
127
+ assert_template_result('result', "{{ blank.x }}", assigns)
128
+ assert_template_result('result', "{{ blank['x'] }}", assigns)
129
+ end
130
+
119
131
  def test_contains_in_id
120
132
  assert_template_result(' YES ', '{% if containsallshipments == true %} YES {% endif %}', 'containsallshipments' => true)
121
133
  end