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.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -0
- data/Rakefile +19 -14
- data/ext/better_html_ext/better_html.h +1 -0
- data/ext/better_html_ext/extconf.rb +16 -0
- data/ext/better_html_ext/html_tokenizer.c +12 -0
- data/ext/better_html_ext/html_tokenizer.h +7 -0
- data/ext/better_html_ext/parser.c +793 -0
- data/ext/better_html_ext/parser.h +93 -0
- data/ext/better_html_ext/tokenizer.c +717 -0
- data/ext/better_html_ext/tokenizer.h +80 -0
- data/lib/better_html/ast/iterator.rb +14 -9
- data/lib/better_html/ast/node.rb +4 -2
- data/lib/better_html/better_erb/erubi_implementation.rb +43 -39
- data/lib/better_html/better_erb/runtime_checks.rb +140 -133
- data/lib/better_html/better_erb/validated_output_buffer.rb +30 -22
- data/lib/better_html/better_erb.rb +58 -54
- data/lib/better_html/config.rb +7 -4
- data/lib/better_html/errors.rb +4 -2
- data/lib/better_html/helpers.rb +7 -3
- data/lib/better_html/html_attributes.rb +6 -2
- data/lib/better_html/parser.rb +21 -14
- data/lib/better_html/railtie.rb +8 -4
- data/lib/better_html/test_helper/ruby_node.rb +15 -10
- data/lib/better_html/test_helper/safe_erb/allowed_script_type.rb +8 -4
- data/lib/better_html/test_helper/safe_erb/base.rb +12 -9
- data/lib/better_html/test_helper/safe_erb/no_javascript_tag_helper.rb +7 -3
- data/lib/better_html/test_helper/safe_erb/no_statements.rb +7 -3
- data/lib/better_html/test_helper/safe_erb/script_interpolation.rb +9 -4
- data/lib/better_html/test_helper/safe_erb/tag_interpolation.rb +23 -20
- data/lib/better_html/test_helper/safe_erb_tester.rb +33 -31
- data/lib/better_html/test_helper/safe_lodash_tester.rb +36 -35
- data/lib/better_html/test_helper/safety_error.rb +2 -0
- data/lib/better_html/tokenizer/base_erb.rb +14 -10
- data/lib/better_html/tokenizer/html_erb.rb +3 -2
- data/lib/better_html/tokenizer/html_lodash.rb +22 -14
- data/lib/better_html/tokenizer/javascript_erb.rb +3 -1
- data/lib/better_html/tokenizer/location.rb +17 -6
- data/lib/better_html/tokenizer/token.rb +2 -0
- data/lib/better_html/tokenizer/token_array.rb +8 -8
- data/lib/better_html/tree/attribute.rb +10 -6
- data/lib/better_html/tree/attributes_list.rb +9 -5
- data/lib/better_html/tree/tag.rb +10 -6
- data/lib/better_html/version.rb +3 -1
- data/lib/better_html.rb +19 -17
- data/lib/tasks/better_html_tasks.rake +1 -0
- metadata +39 -147
- data/lib/better_html/better_erb/erubis_implementation.rb +0 -44
- data/test/better_html/better_erb/implementation_test.rb +0 -406
- data/test/better_html/errors_test.rb +0 -13
- data/test/better_html/helpers_test.rb +0 -49
- data/test/better_html/parser_test.rb +0 -314
- data/test/better_html/test_helper/ruby_node_test.rb +0 -288
- data/test/better_html/test_helper/safe_erb/allowed_script_type_test.rb +0 -46
- data/test/better_html/test_helper/safe_erb/no_javascript_tag_helper_test.rb +0 -37
- data/test/better_html/test_helper/safe_erb/no_statements_test.rb +0 -129
- data/test/better_html/test_helper/safe_erb/script_interpolation_test.rb +0 -149
- data/test/better_html/test_helper/safe_erb/tag_interpolation_test.rb +0 -303
- data/test/better_html/test_helper/safe_lodash_tester_test.rb +0 -90
- data/test/better_html/tokenizer/html_erb_test.rb +0 -180
- data/test/better_html/tokenizer/html_lodash_test.rb +0 -98
- data/test/better_html/tokenizer/location_test.rb +0 -75
- data/test/better_html/tokenizer/token_array_test.rb +0 -146
- data/test/better_html/tokenizer/token_test.rb +0 -15
- data/test/dummy/README.rdoc +0 -28
- data/test/dummy/Rakefile +0 -6
- data/test/dummy/app/assets/javascripts/application.js +0 -13
- data/test/dummy/app/assets/stylesheets/application.css +0 -15
- data/test/dummy/app/controllers/application_controller.rb +0 -5
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/views/layouts/application.html.erb +0 -14
- data/test/dummy/bin/bundle +0 -3
- data/test/dummy/bin/rails +0 -4
- data/test/dummy/bin/rake +0 -4
- data/test/dummy/bin/setup +0 -29
- data/test/dummy/config/application.rb +0 -26
- data/test/dummy/config/boot.rb +0 -5
- data/test/dummy/config/database.yml +0 -25
- data/test/dummy/config/environment.rb +0 -5
- data/test/dummy/config/environments/development.rb +0 -41
- data/test/dummy/config/environments/production.rb +0 -79
- data/test/dummy/config/environments/test.rb +0 -42
- data/test/dummy/config/initializers/assets.rb +0 -11
- data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/test/dummy/config/initializers/cookies_serializer.rb +0 -3
- data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -4
- data/test/dummy/config/initializers/inflections.rb +0 -16
- data/test/dummy/config/initializers/mime_types.rb +0 -4
- data/test/dummy/config/initializers/session_store.rb +0 -3
- data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/test/dummy/config/locales/en.yml +0 -23
- data/test/dummy/config/routes.rb +0 -56
- data/test/dummy/config/secrets.yml +0 -22
- data/test/dummy/config.ru +0 -4
- data/test/dummy/public/404.html +0 -67
- data/test/dummy/public/422.html +0 -67
- data/test/dummy/public/500.html +0 -66
- data/test/dummy/public/favicon.ico +0 -0
- 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
|