better_html 1.0.15 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
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 +47 -56
  18. data/lib/better_html/config.rb +7 -4
  19. data/lib/better_html/errors.rb +15 -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 +22 -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 +34 -32
  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 +19 -15
  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