better_html 1.0.16 → 2.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 (99) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -0
  3. data/Rakefile +19 -14
  4. data/ext/better_html_ext/better_html.h +1 -0
  5. data/ext/better_html_ext/extconf.rb +16 -0
  6. data/ext/better_html_ext/html_tokenizer.c +12 -0
  7. data/ext/better_html_ext/html_tokenizer.h +7 -0
  8. data/ext/better_html_ext/parser.c +793 -0
  9. data/ext/better_html_ext/parser.h +93 -0
  10. data/ext/better_html_ext/tokenizer.c +717 -0
  11. data/ext/better_html_ext/tokenizer.h +80 -0
  12. data/lib/better_html/ast/iterator.rb +14 -9
  13. data/lib/better_html/ast/node.rb +4 -2
  14. data/lib/better_html/better_erb/erubi_implementation.rb +43 -39
  15. data/lib/better_html/better_erb/runtime_checks.rb +140 -133
  16. data/lib/better_html/better_erb/validated_output_buffer.rb +30 -22
  17. data/lib/better_html/better_erb.rb +58 -54
  18. data/lib/better_html/config.rb +7 -4
  19. data/lib/better_html/errors.rb +4 -2
  20. data/lib/better_html/helpers.rb +7 -3
  21. data/lib/better_html/html_attributes.rb +6 -2
  22. data/lib/better_html/parser.rb +21 -14
  23. data/lib/better_html/railtie.rb +8 -4
  24. data/lib/better_html/test_helper/ruby_node.rb +15 -10
  25. data/lib/better_html/test_helper/safe_erb/allowed_script_type.rb +8 -4
  26. data/lib/better_html/test_helper/safe_erb/base.rb +12 -9
  27. data/lib/better_html/test_helper/safe_erb/no_javascript_tag_helper.rb +7 -3
  28. data/lib/better_html/test_helper/safe_erb/no_statements.rb +7 -3
  29. data/lib/better_html/test_helper/safe_erb/script_interpolation.rb +9 -4
  30. data/lib/better_html/test_helper/safe_erb/tag_interpolation.rb +23 -20
  31. data/lib/better_html/test_helper/safe_erb_tester.rb +33 -31
  32. data/lib/better_html/test_helper/safe_lodash_tester.rb +36 -35
  33. data/lib/better_html/test_helper/safety_error.rb +2 -0
  34. data/lib/better_html/tokenizer/base_erb.rb +14 -10
  35. data/lib/better_html/tokenizer/html_erb.rb +3 -2
  36. data/lib/better_html/tokenizer/html_lodash.rb +22 -14
  37. data/lib/better_html/tokenizer/javascript_erb.rb +3 -1
  38. data/lib/better_html/tokenizer/location.rb +17 -6
  39. data/lib/better_html/tokenizer/token.rb +2 -0
  40. data/lib/better_html/tokenizer/token_array.rb +8 -8
  41. data/lib/better_html/tree/attribute.rb +10 -6
  42. data/lib/better_html/tree/attributes_list.rb +9 -5
  43. data/lib/better_html/tree/tag.rb +10 -6
  44. data/lib/better_html/version.rb +3 -1
  45. data/lib/better_html.rb +19 -17
  46. data/lib/tasks/better_html_tasks.rake +1 -0
  47. metadata +39 -147
  48. data/lib/better_html/better_erb/erubis_implementation.rb +0 -44
  49. data/test/better_html/better_erb/implementation_test.rb +0 -406
  50. data/test/better_html/errors_test.rb +0 -13
  51. data/test/better_html/helpers_test.rb +0 -49
  52. data/test/better_html/parser_test.rb +0 -314
  53. data/test/better_html/test_helper/ruby_node_test.rb +0 -288
  54. data/test/better_html/test_helper/safe_erb/allowed_script_type_test.rb +0 -46
  55. data/test/better_html/test_helper/safe_erb/no_javascript_tag_helper_test.rb +0 -37
  56. data/test/better_html/test_helper/safe_erb/no_statements_test.rb +0 -129
  57. data/test/better_html/test_helper/safe_erb/script_interpolation_test.rb +0 -149
  58. data/test/better_html/test_helper/safe_erb/tag_interpolation_test.rb +0 -303
  59. data/test/better_html/test_helper/safe_lodash_tester_test.rb +0 -90
  60. data/test/better_html/tokenizer/html_erb_test.rb +0 -180
  61. data/test/better_html/tokenizer/html_lodash_test.rb +0 -98
  62. data/test/better_html/tokenizer/location_test.rb +0 -75
  63. data/test/better_html/tokenizer/token_array_test.rb +0 -146
  64. data/test/better_html/tokenizer/token_test.rb +0 -15
  65. data/test/dummy/README.rdoc +0 -28
  66. data/test/dummy/Rakefile +0 -6
  67. data/test/dummy/app/assets/javascripts/application.js +0 -13
  68. data/test/dummy/app/assets/stylesheets/application.css +0 -15
  69. data/test/dummy/app/controllers/application_controller.rb +0 -5
  70. data/test/dummy/app/helpers/application_helper.rb +0 -2
  71. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  72. data/test/dummy/bin/bundle +0 -3
  73. data/test/dummy/bin/rails +0 -4
  74. data/test/dummy/bin/rake +0 -4
  75. data/test/dummy/bin/setup +0 -29
  76. data/test/dummy/config/application.rb +0 -26
  77. data/test/dummy/config/boot.rb +0 -5
  78. data/test/dummy/config/database.yml +0 -25
  79. data/test/dummy/config/environment.rb +0 -5
  80. data/test/dummy/config/environments/development.rb +0 -41
  81. data/test/dummy/config/environments/production.rb +0 -79
  82. data/test/dummy/config/environments/test.rb +0 -42
  83. data/test/dummy/config/initializers/assets.rb +0 -11
  84. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  85. data/test/dummy/config/initializers/cookies_serializer.rb +0 -3
  86. data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  87. data/test/dummy/config/initializers/inflections.rb +0 -16
  88. data/test/dummy/config/initializers/mime_types.rb +0 -4
  89. data/test/dummy/config/initializers/session_store.rb +0 -3
  90. data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
  91. data/test/dummy/config/locales/en.yml +0 -23
  92. data/test/dummy/config/routes.rb +0 -56
  93. data/test/dummy/config/secrets.yml +0 -22
  94. data/test/dummy/config.ru +0 -4
  95. data/test/dummy/public/404.html +0 -67
  96. data/test/dummy/public/422.html +0 -67
  97. data/test/dummy/public/500.html +0 -66
  98. data/test/dummy/public/favicon.ico +0 -0
  99. data/test/test_helper.rb +0 -29
@@ -1,314 +0,0 @@
1
- require 'test_helper'
2
- require 'better_html/parser'
3
- require 'ast'
4
-
5
- module BetterHtml
6
- class ParserTest < ActiveSupport::TestCase
7
- include ::AST::Sexp
8
-
9
- test "parse empty document" do
10
- tree = Parser.new(buffer(''))
11
-
12
- assert_equal s(:document), tree.ast
13
- end
14
-
15
- test "parser errors" do
16
- tree = Parser.new(buffer('<>'))
17
-
18
- assert_equal 1, tree.parser_errors.size
19
- assert_equal "expected '/' or tag name", tree.parser_errors[0].message
20
- assert_equal 1...2, tree.parser_errors[0].location.range
21
- assert_equal <<~EOF.strip, tree.parser_errors[0].location.line_source_with_underline
22
- <>
23
- ^
24
- EOF
25
- end
26
-
27
- test "consume cdata nodes" do
28
- code = "<![CDATA[ foo ]]>"
29
- tree = Parser.new(buffer(code))
30
-
31
- assert_equal s(:document, s(:cdata, ' foo ')), tree.ast
32
- assert_equal code, tree.ast.loc.source
33
- end
34
-
35
- test "unterminated cdata nodes are consumed until end" do
36
- code = "<![CDATA[ foo"
37
- tree = Parser.new(buffer(code))
38
-
39
- assert_equal s(:document, s(:cdata, ' foo')), tree.ast
40
- assert_equal code, tree.ast.loc.source
41
- end
42
-
43
- test "consume cdata with interpolation" do
44
- code = "<![CDATA[ foo <%= bar %> baz ]]>"
45
- tree = Parser.new(buffer(code))
46
-
47
- assert_equal s(:document,
48
- s(:cdata,
49
- " foo ",
50
- s(:erb, s(:indicator, '='), nil, s(:code, " bar "), nil),
51
- " baz "
52
- )),
53
- tree.ast
54
- assert_equal code, tree.ast.loc.source
55
- end
56
-
57
- test "consume comment nodes" do
58
- tree = Parser.new(buffer("<!-- foo -->"))
59
-
60
- assert_equal s(:document, s(:comment, ' foo ')), tree.ast
61
- end
62
-
63
- test "unterminated comment nodes are consumed until end" do
64
- tree = Parser.new(buffer("<!-- foo"))
65
-
66
- assert_equal s(:document, s(:comment, ' foo')), tree.ast
67
- end
68
-
69
- test "consume comment with interpolation" do
70
- tree = Parser.new(buffer("<!-- foo <%= bar %> baz -->"))
71
-
72
- assert_equal s(:document,
73
- s(:comment,
74
- " foo ",
75
- s(:erb, s(:indicator, "="), nil, s(:code, " bar "), nil),
76
- " baz "
77
- )),
78
- tree.ast
79
- end
80
-
81
- test "consume tag nodes" do
82
- tree = Parser.new(buffer("<div>"))
83
- assert_equal s(:document, s(:tag, nil, s(:tag_name, "div"), nil, nil)), tree.ast
84
- end
85
-
86
- test "tag without name" do
87
- tree = Parser.new(buffer("foo < bar"))
88
- assert_equal s(:document,
89
- s(:text, "foo "),
90
- s(:tag, nil, nil,
91
- s(:tag_attributes,
92
- s(:attribute, s(:attribute_name, 'bar'), nil, nil)
93
- ),
94
- nil
95
- )
96
- ), tree.ast
97
- end
98
-
99
- test "consume tag nodes with solidus" do
100
- tree = Parser.new(buffer("</div>"))
101
- assert_equal s(:document, s(:tag, s(:solidus), s(:tag_name, "div"), nil, nil)), tree.ast
102
- end
103
-
104
- test "sets self_closing when appropriate" do
105
- tree = Parser.new(buffer("<div/>"))
106
- assert_equal s(:document, s(:tag, nil, s(:tag_name, "div"), nil, s(:solidus))), tree.ast
107
- end
108
-
109
- test "consume tag nodes until name ends" do
110
- tree = Parser.new(buffer("<div/>"))
111
- assert_equal s(:document, s(:tag, nil, s(:tag_name, "div"), nil, s(:solidus))), tree.ast
112
-
113
- tree = Parser.new(buffer("<div "))
114
- assert_equal s(:document, s(:tag, nil, s(:tag_name, "div"), nil, nil)), tree.ast
115
- end
116
-
117
- test "consume tag nodes with interpolation" do
118
- tree = Parser.new(buffer("<ns:<%= name %>-thing>"))
119
- assert_equal s(:document,
120
- s(:tag,
121
- nil,
122
- s(:tag_name, "ns:", s(:erb, s(:indicator, "="), nil, s(:code, " name "), nil), "-thing"),
123
- nil,
124
- nil
125
- )), tree.ast
126
- end
127
-
128
- test "consume tag attributes with erb" do
129
- tree = Parser.new(buffer("<div class=foo <%= erb %> name=bar>"))
130
- assert_equal s(:document,
131
- s(:tag, nil,
132
- s(:tag_name, "div"),
133
- s(:tag_attributes,
134
- s(:attribute,
135
- s(:attribute_name, "class"),
136
- s(:equal),
137
- s(:attribute_value, "foo")
138
- ),
139
- s(:erb, s(:indicator, "="), nil,
140
- s(:code, " erb "), nil),
141
- s(:attribute,
142
- s(:attribute_name, "name"),
143
- s(:equal),
144
- s(:attribute_value, "bar")
145
- ),
146
- ),
147
- nil
148
- )), tree.ast
149
- end
150
-
151
- test "consume tag attributes nodes unquoted value" do
152
- tree = Parser.new(buffer("<div foo=bar>"))
153
- assert_equal s(:document,
154
- s(:tag, nil,
155
- s(:tag_name, "div"),
156
- s(:tag_attributes,
157
- s(:attribute,
158
- s(:attribute_name, "foo"),
159
- s(:equal),
160
- s(:attribute_value, "bar")
161
- )
162
- ),
163
- nil
164
- )), tree.ast
165
- end
166
-
167
- test "consume attributes without name" do
168
- tree = Parser.new(buffer("<div 'thing'>"))
169
- assert_equal s(:document,
170
- s(:tag, nil,
171
- s(:tag_name, "div"),
172
- s(:tag_attributes,
173
- s(:attribute,
174
- nil,
175
- nil,
176
- s(:attribute_value, s(:quote, "'"), "thing", s(:quote, "'"))
177
- )
178
- ),
179
- nil
180
- )), tree.ast
181
- end
182
-
183
- test "consume tag attributes nodes quoted value" do
184
- tree = Parser.new(buffer("<div foo=\"bar\">"))
185
- assert_equal s(:document,
186
- s(:tag, nil,
187
- s(:tag_name, "div"),
188
- s(:tag_attributes,
189
- s(:attribute,
190
- s(:attribute_name, "foo"),
191
- s(:equal),
192
- s(:attribute_value, s(:quote, "\""), "bar", s(:quote, "\""))
193
- )
194
- ),
195
- nil
196
- )), tree.ast
197
- end
198
-
199
- test "consume tag attributes nodes interpolation in name and value" do
200
- tree = Parser.new(buffer("<div data-<%= foo %>=\"some <%= value %> foo\">"))
201
- assert_equal s(:document,
202
- s(:tag, nil,
203
- s(:tag_name, "div"),
204
- s(:tag_attributes,
205
- s(:attribute,
206
- s(:attribute_name, "data-", s(:erb, s(:indicator, "="), nil, s(:code, " foo "), nil)),
207
- s(:equal),
208
- s(:attribute_value,
209
- s(:quote, "\""),
210
- "some ",
211
- s(:erb, s(:indicator, "="), nil, s(:code, " value "), nil),
212
- " foo",
213
- s(:quote, "\""),
214
- ),
215
- )
216
- ),
217
- nil
218
- )), tree.ast
219
- end
220
-
221
- test "consume text nodes" do
222
- tree = Parser.new(buffer("here is <%= some %> text"))
223
-
224
- assert_equal s(:document,
225
- s(:text,
226
- "here is ",
227
- s(:erb, s(:indicator, "="), nil, s(:code, " some "), nil),
228
- " text"
229
- )), tree.ast
230
- end
231
-
232
- test "javascript template parsing works" do
233
- tree = Parser.new(buffer("here is <%= some %> text"), template_language: :javascript)
234
-
235
- assert_equal s(:document,
236
- s(:text,
237
- "here is ",
238
- s(:erb, s(:indicator, "="), nil, s(:code, " some "), nil),
239
- " text"
240
- )), tree.ast
241
- end
242
-
243
- test "javascript template does not consume html tags" do
244
- tree = Parser.new(buffer("<div <%= some %> />"), template_language: :javascript)
245
-
246
- assert_equal s(:document,
247
- s(:text,
248
- "<div ",
249
- s(:erb, s(:indicator, "="), nil, s(:code, " some "), nil),
250
- " />"
251
- )), tree.ast
252
- end
253
-
254
- test "lodash template parsing works" do
255
- tree = Parser.new(buffer('<div class="[%= foo %]">'), template_language: :lodash)
256
-
257
- assert_equal s(:document,
258
- s(:tag,
259
- nil,
260
- s(:tag_name, "div"),
261
- s(:tag_attributes,
262
- s(:attribute,
263
- s(:attribute_name, "class"),
264
- s(:equal),
265
- s(:attribute_value,
266
- s(:quote, "\""),
267
- s(:lodash, s(:indicator, "="), s(:code, " foo ")),
268
- s(:quote, "\"")
269
- )
270
- )
271
- ),
272
- nil
273
- )
274
- ), tree.ast
275
- end
276
-
277
- test "nodes are all nested under document" do
278
- tree = Parser.new(buffer(<<~HTML))
279
- some text
280
- <!-- a comment -->
281
- some more text
282
- <%= an erb tag -%>
283
- <div class="foo">
284
- content
285
- </div>
286
- HTML
287
-
288
- assert_equal s(:document,
289
- s(:text, "some text\n"),
290
- s(:comment, " a comment "),
291
- s(:text,
292
- "\nsome more text\n",
293
- s(:erb, s(:indicator, '='), nil, s(:code, ' an erb tag '), s(:trim)),
294
- "\n"
295
- ),
296
- s(:tag,
297
- nil,
298
- s(:tag_name, "div"),
299
- s(:tag_attributes,
300
- s(:attribute,
301
- s(:attribute_name, "class"),
302
- s(:equal),
303
- s(:attribute_value, s(:quote, "\""), "foo", s(:quote, "\""))
304
- )
305
- ),
306
- nil
307
- ),
308
- s(:text, "\n content\n"),
309
- s(:tag, s(:solidus), s(:tag_name, 'div'), nil, nil),
310
- s(:text, "\n"),
311
- ), tree.ast
312
- end
313
- end
314
- end
@@ -1,288 +0,0 @@
1
- require 'test_helper'
2
- require 'better_html/test_helper/ruby_node'
3
-
4
- module BetterHtml
5
- module TestHelper
6
- class RubyNodeTest < ActiveSupport::TestCase
7
- include ::AST::Sexp
8
-
9
- test "simple call" do
10
- expr = BetterHtml::TestHelper::RubyNode.parse("foo")
11
- assert_equal 1, expr.return_values.count
12
- assert_nil expr.return_values.first.receiver
13
- assert_equal :foo, expr.return_values.first.method_name
14
- assert_equal [], expr.return_values.first.arguments
15
- refute_predicate expr, :static_return_value?
16
- end
17
-
18
- test "instance call" do
19
- expr = BetterHtml::TestHelper::RubyNode.parse("foo.bar")
20
- assert_equal 1, expr.return_values.count
21
- assert_equal s(:send, nil, :foo), expr.return_values.first.receiver
22
- assert_equal :bar, expr.return_values.first.method_name
23
- assert_equal [], expr.return_values.first.arguments
24
- refute_predicate expr, :static_return_value?
25
- end
26
-
27
- test "instance call with arguments" do
28
- expr = BetterHtml::TestHelper::RubyNode.parse("foo(x).bar")
29
- assert_equal 1, expr.return_values.count
30
- assert_equal s(:send, nil, :foo, s(:send, nil, :x)), expr.return_values.first.receiver
31
- assert_equal :bar, expr.return_values.first.method_name
32
- assert_equal [], expr.return_values.first.arguments
33
- refute_predicate expr, :static_return_value?
34
- end
35
-
36
- test "instance call with parenthesis" do
37
- expr = BetterHtml::TestHelper::RubyNode.parse("(foo).bar")
38
- assert_equal 1, expr.return_values.count
39
- assert_equal s(:begin, s(:send, nil, :foo)), expr.return_values.first.receiver
40
- assert_equal :bar, expr.return_values.first.method_name
41
- assert_equal [], expr.return_values.first.arguments
42
- refute_predicate expr, :static_return_value?
43
- end
44
-
45
- test "instance call with parenthesis 2" do
46
- expr = BetterHtml::TestHelper::RubyNode.parse("(foo)")
47
- assert_equal 1, expr.return_values.count
48
- assert_nil expr.return_values.first.receiver
49
- assert_equal :foo, expr.return_values.first.method_name
50
- assert_equal [], expr.return_values.first.arguments
51
- refute_predicate expr, :static_return_value?
52
- end
53
-
54
- test "command call" do
55
- expr = BetterHtml::TestHelper::RubyNode.parse("foo bar")
56
- assert_equal 1, expr.return_values.count
57
- assert_nil expr.return_values.first.receiver
58
- assert_equal :foo, expr.return_values.first.method_name
59
- assert_equal [s(:send, nil, :bar)], expr.return_values.first.arguments
60
- refute_predicate expr, :static_return_value?
61
- end
62
-
63
- test "command call with block" do
64
- expr = BetterHtml::TestHelper::RubyNode.parse("foo bar do")
65
- assert_equal 1, expr.return_values.count
66
- assert_nil expr.return_values.first.receiver
67
- assert_equal :foo, expr.return_values.first.method_name
68
- assert_equal [s(:send, nil, :bar)], expr.return_values.first.arguments
69
- refute_predicate expr, :static_return_value?
70
- end
71
-
72
- test "call with parameters" do
73
- expr = BetterHtml::TestHelper::RubyNode.parse("foo(bar)")
74
- assert_equal 1, expr.return_values.count
75
- assert_nil expr.return_values.first.receiver
76
- assert_equal :foo, expr.return_values.first.method_name
77
- assert_equal [s(:send, nil, :bar)], expr.return_values.first.arguments
78
- refute_predicate expr, :static_return_value?
79
- end
80
-
81
- test "instance call with parameters" do
82
- expr = BetterHtml::TestHelper::RubyNode.parse("foo.bar(baz, x)")
83
- assert_equal 1, expr.return_values.count
84
- assert_equal s(:send, nil, :foo), expr.return_values.first.receiver
85
- assert_equal :bar, expr.return_values.first.method_name
86
- assert_equal [s(:send, nil, :baz), s(:send, nil, :x)], expr.return_values.first.arguments
87
- refute_predicate expr, :static_return_value?
88
- end
89
-
90
- test "call with parameters with if conditional modifier" do
91
- expr = BetterHtml::TestHelper::RubyNode.parse("foo(bar) if something?")
92
- assert_equal 1, expr.return_values.count
93
- assert_nil expr.return_values.first.receiver
94
- assert_equal :foo, expr.return_values.first.method_name
95
- assert_equal [s(:send, nil, :bar)], expr.return_values.first.arguments
96
- refute_predicate expr, :static_return_value?
97
- end
98
-
99
- test "call with parameters with unless conditional modifier" do
100
- expr = BetterHtml::TestHelper::RubyNode.parse("foo(bar) unless something?")
101
- assert_equal 1, expr.return_values.count
102
- assert_nil expr.return_values.first.receiver
103
- assert_equal :foo, expr.return_values.first.method_name
104
- assert_equal [s(:send, nil, :bar)], expr.return_values.first.arguments
105
- refute_predicate expr, :static_return_value?
106
- end
107
-
108
- test "expression call in ternary" do
109
- expr = BetterHtml::TestHelper::RubyNode.parse("something? ? foo : bar")
110
- assert_equal 2, expr.return_values.count
111
- refute_predicate expr, :static_return_value?
112
-
113
- assert_nil expr.return_values.to_a[0].receiver
114
- assert_equal :foo, expr.return_values.to_a[0].method_name
115
- assert_equal [], expr.return_values.to_a[0].arguments
116
-
117
- assert_nil expr.return_values.to_a[1].receiver
118
- assert_equal :bar, expr.return_values.to_a[1].method_name
119
- assert_equal [], expr.return_values.to_a[1].arguments
120
- end
121
-
122
- test "expression call with args in ternary" do
123
- expr = BetterHtml::TestHelper::RubyNode.parse("something? ? foo(x) : bar(x)")
124
- assert_equal 2, expr.return_values.count
125
-
126
- assert_nil expr.return_values.to_a[0].receiver
127
- assert_equal :foo, expr.return_values.to_a[0].method_name
128
- assert_equal [s(:send, nil, :x)], expr.return_values.to_a[0].arguments
129
-
130
- assert_nil expr.return_values.to_a[1].receiver
131
- assert_equal :bar, expr.return_values.to_a[1].method_name
132
- assert_equal [s(:send, nil, :x)], expr.return_values.to_a[1].arguments
133
- refute_predicate expr, :static_return_value?
134
- end
135
-
136
- test "string without interpolation" do
137
- expr = BetterHtml::TestHelper::RubyNode.parse('"foo"')
138
- assert_equal 1, expr.return_values.count
139
- assert_equal [s(:str, "foo")], expr.return_values.to_a
140
- assert_predicate expr, :static_return_value?
141
- end
142
-
143
- test "string with interpolation" do
144
- expr = BetterHtml::TestHelper::RubyNode.parse('"foo #{bar}"')
145
- method_calls = expr.return_values.select(&:method_call?)
146
- assert_equal 1, method_calls.count
147
- assert_nil method_calls.first.receiver
148
- assert_equal :bar, method_calls.first.method_name
149
- assert_equal [], method_calls.first.arguments
150
- refute_predicate expr, :static_return_value?
151
- end
152
-
153
- test "ternary in string with interpolation" do
154
- expr = BetterHtml::TestHelper::RubyNode.parse('"foo #{foo? ? bar : baz}"')
155
- method_calls = expr.return_values.select(&:method_call?)
156
- assert_equal 2, method_calls.count
157
-
158
- assert_nil method_calls.first.receiver
159
- assert_equal :bar, method_calls.first.method_name
160
- assert_equal [], method_calls.first.arguments
161
-
162
- assert_nil method_calls.last.receiver
163
- assert_equal :baz, method_calls.last.method_name
164
- assert_equal [], method_calls.first.arguments
165
- refute_predicate expr, :static_return_value?
166
- end
167
-
168
- test "assignment to variable" do
169
- expr = BetterHtml::TestHelper::RubyNode.parse('x = foo.bar')
170
- assert_equal 1, expr.return_values.count
171
- assert_equal s(:send, nil, :foo), expr.return_values.first.receiver
172
- assert_equal :bar, expr.return_values.first.method_name
173
- assert_equal [], expr.return_values.first.arguments
174
- refute_predicate expr, :static_return_value?
175
- end
176
-
177
- test "assignment to variable with command call" do
178
- expr = BetterHtml::TestHelper::RubyNode.parse('raw x = foo.bar')
179
- assert_equal 1, expr.return_values.count
180
- assert_nil expr.return_values.first.receiver
181
- assert_equal :raw, expr.return_values.first.method_name
182
- assert_equal [s(:lvasgn, :x, s(:send, s(:send, nil, :foo), :bar))], expr.return_values.first.arguments
183
- refute_predicate expr, :static_return_value?
184
- end
185
-
186
- test "assignment with instance call" do
187
- expr = BetterHtml::TestHelper::RubyNode.parse('(x = foo).bar')
188
- assert_equal 1, expr.return_values.count
189
- assert_equal s(:begin, s(:lvasgn, :x, s(:send, nil, :foo))), expr.return_values.first.receiver
190
- assert_equal :bar, expr.return_values.first.method_name
191
- assert_equal [], expr.return_values.first.arguments
192
- refute_predicate expr, :static_return_value?
193
- end
194
-
195
- test "assignment to multiple variables" do
196
- expr = BetterHtml::TestHelper::RubyNode.parse('x, y = foo.bar')
197
- assert_equal 1, expr.return_values.count
198
- assert_equal s(:send, nil, :foo), expr.return_values.first.receiver
199
- assert_equal :bar, expr.return_values.first.method_name
200
- assert_equal [], expr.return_values.first.arguments
201
- refute_predicate expr, :static_return_value?
202
- end
203
-
204
- test "safe navigation operator" do
205
- expr = BetterHtml::TestHelper::RubyNode.parse('foo&.bar')
206
- assert_equal 1, expr.return_values.count
207
- assert_equal s(:send, nil, :foo), expr.return_values.to_a[0].receiver
208
- assert_equal :bar, expr.return_values.to_a[0].method_name
209
- assert_equal [], expr.return_values.to_a[0].arguments
210
- refute_predicate expr, :static_return_value?
211
- end
212
-
213
- test "instance variable" do
214
- expr = BetterHtml::TestHelper::RubyNode.parse('@foo')
215
- assert_equal 0, expr.return_values.select(&:method_call?).count
216
- refute_predicate expr, :static_return_value?
217
- end
218
-
219
- test "instance method on variable" do
220
- expr = BetterHtml::TestHelper::RubyNode.parse('@foo.bar')
221
- assert_equal 1, expr.return_values.count
222
- assert_equal s(:ivar, :@foo), expr.return_values.first.receiver
223
- assert_equal :bar, expr.return_values.first.method_name
224
- assert_equal [], expr.return_values.first.arguments
225
- refute_predicate expr, :static_return_value?
226
- end
227
-
228
- test "index into array" do
229
- expr = BetterHtml::TestHelper::RubyNode.parse('local_assigns[:text_class] if local_assigns[:text_class]')
230
- assert_equal 1, expr.return_values.count
231
- assert_equal s(:send, nil, :local_assigns), expr.return_values.first.receiver
232
- assert_equal :[], expr.return_values.first.method_name
233
- assert_equal [s(:sym, :text_class)], expr.return_values.first.arguments
234
- refute_predicate expr, :static_return_value?
235
- end
236
-
237
- test "static_return_value? for ivar" do
238
- expr = BetterHtml::TestHelper::RubyNode.parse('@foo')
239
- refute_predicate expr, :static_return_value?
240
- end
241
-
242
- test "static_return_value? for str" do
243
- expr = BetterHtml::TestHelper::RubyNode.parse("'str'")
244
- assert_predicate expr, :static_return_value?
245
- end
246
-
247
- test "static_return_value? for int" do
248
- expr = BetterHtml::TestHelper::RubyNode.parse("1")
249
- assert_predicate expr, :static_return_value?
250
- end
251
-
252
- test "static_return_value? for bool" do
253
- expr = BetterHtml::TestHelper::RubyNode.parse("true")
254
- assert_predicate expr, :static_return_value?
255
- end
256
-
257
- test "static_return_value? for nil" do
258
- expr = BetterHtml::TestHelper::RubyNode.parse("nil")
259
- assert_predicate expr, :static_return_value?
260
- end
261
-
262
- test "static_return_value? for dstr without interpolate" do
263
- expr = BetterHtml::TestHelper::RubyNode.parse('"str"')
264
- assert_predicate expr, :static_return_value?
265
- end
266
-
267
- test "static_return_value? for dstr with interpolate" do
268
- expr = BetterHtml::TestHelper::RubyNode.parse('"str #{foo}"')
269
- refute_predicate expr, :static_return_value?
270
- end
271
-
272
- test "static_return_value? with safe ternary" do
273
- expr = BetterHtml::TestHelper::RubyNode.parse('foo ? \'a\' : \'b\'')
274
- assert_predicate expr, :static_return_value?
275
- end
276
-
277
- test "static_return_value? with safe conditional" do
278
- expr = BetterHtml::TestHelper::RubyNode.parse('\'foo\' if bar?')
279
- assert_predicate expr, :static_return_value?
280
- end
281
-
282
- test "static_return_value? with safe assignment" do
283
- expr = BetterHtml::TestHelper::RubyNode.parse('x = \'foo\'')
284
- assert_predicate expr, :static_return_value?
285
- end
286
- end
287
- end
288
- end
@@ -1,46 +0,0 @@
1
- require 'test_helper'
2
- require 'better_html/parser'
3
- require 'better_html/test_helper/safe_erb/allowed_script_type'
4
-
5
- module BetterHtml
6
- module TestHelper
7
- module SafeErb
8
- class AllowedScriptTypeTest < ActiveSupport::TestCase
9
- setup do
10
- @config = BetterHtml::Config.new(
11
- javascript_safe_methods: ['j', 'escape_javascript', 'to_json'],
12
- javascript_attribute_names: [/\Aon/i, 'data-eval'],
13
- )
14
- end
15
-
16
- test "allowed script type" do
17
- errors = validate(<<-EOF).errors
18
- <script type="text/javascript">
19
- </script>
20
- EOF
21
-
22
- assert_predicate errors, :empty?
23
- end
24
-
25
- test "disallowed script types" do
26
- errors = validate(<<-EOF).errors
27
- <script type="text/bogus">
28
- </script>
29
- EOF
30
-
31
- assert_equal 1, errors.size
32
- assert_equal 'type="text/bogus"', errors.first.location.source
33
- assert_equal "text/bogus is not a valid type, valid types are text/javascript, text/template, text/html", errors.first.message
34
- end
35
-
36
- private
37
- def validate(data, template_language: :html)
38
- parser = BetterHtml::Parser.new(buffer(data), template_language: template_language)
39
- tester = BetterHtml::TestHelper::SafeErb::AllowedScriptType.new(parser, config: @config)
40
- tester.validate
41
- tester
42
- end
43
- end
44
- end
45
- end
46
- end
@@ -1,37 +0,0 @@
1
- require 'test_helper'
2
- require 'better_html/test_helper/safe_erb/no_javascript_tag_helper'
3
-
4
- module BetterHtml
5
- module TestHelper
6
- module SafeErb
7
- class NoJavascriptTagHelperTest < ActiveSupport::TestCase
8
- setup do
9
- @config = BetterHtml::Config.new(
10
- javascript_safe_methods: ['j', 'escape_javascript', 'to_json'],
11
- javascript_attribute_names: [/\Aon/i, 'data-eval'],
12
- )
13
- end
14
-
15
- test "javascript_tag helper is not allowed because it parses as text and unsafe erb cannot be detected" do
16
- errors = validate(<<-EOF).errors
17
- <%= javascript_tag do %>
18
- if (a < 1) { <%= unsafe %> }
19
- <% end %>
20
- EOF
21
-
22
- assert_equal 1, errors.size
23
- assert_equal '<%= javascript_tag do %>', errors.first.location.source
24
- assert_includes "'javascript_tag do' syntax is deprecated; use inline <script> instead", errors.first.message
25
- end
26
-
27
- private
28
- def validate(data, template_language: :html)
29
- parser = BetterHtml::Parser.new(buffer(data), template_language: template_language)
30
- tester = BetterHtml::TestHelper::SafeErb::NoJavascriptTagHelper.new(parser, config: @config)
31
- tester.validate
32
- tester
33
- end
34
- end
35
- end
36
- end
37
- end