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,406 +0,0 @@
|
|
|
1
|
-
require 'test_helper'
|
|
2
|
-
require 'ostruct'
|
|
3
|
-
require 'better_html/better_erb'
|
|
4
|
-
require 'json'
|
|
5
|
-
|
|
6
|
-
class BetterHtml::BetterErb::ImplementationTest < ActiveSupport::TestCase
|
|
7
|
-
test "simple template rendering" do
|
|
8
|
-
assert_equal "<foo>some value<foo>",
|
|
9
|
-
render("<foo><%= bar %><foo>", locals: { bar: 'some value' })
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
test "html_safe interpolation" do
|
|
13
|
-
assert_equal "<foo><bar /><foo>",
|
|
14
|
-
render("<foo><%= bar %><foo>", locals: { bar: '<bar />'.html_safe })
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
test "non html_safe interpolation" do
|
|
18
|
-
assert_equal "<foo><bar /><foo>",
|
|
19
|
-
render("<foo><%= bar %><foo>", locals: { bar: '<bar />' })
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
test "interpolate non-html_safe inside attribute is escaped" do
|
|
23
|
-
assert_equal "<a href=\" '">x \">",
|
|
24
|
-
render("<a href=\"<%= value %>\">", locals: { value: ' \'">x ' })
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
test "interpolate html_safe inside attribute is magically force-escaped" do
|
|
28
|
-
e = assert_raises(BetterHtml::UnsafeHtmlError) do
|
|
29
|
-
render("<a href=\"<%= value %>\">", locals: { value: ' \'">x '.html_safe })
|
|
30
|
-
end
|
|
31
|
-
assert_equal "Detected invalid characters as part of the interpolation "\
|
|
32
|
-
"into a quoted attribute value. The value cannot contain the character \".", e.message
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
test "interpolate html_safe inside single quoted attribute" do
|
|
36
|
-
config = build_config(allow_single_quoted_attributes: true)
|
|
37
|
-
e = assert_raises(BetterHtml::UnsafeHtmlError) do
|
|
38
|
-
render("<a href=\'<%= value %>\'>", config: config, locals: { value: ' \'">x '.html_safe })
|
|
39
|
-
end
|
|
40
|
-
assert_equal "Detected invalid characters as part of the interpolation "\
|
|
41
|
-
"into a quoted attribute value. The value cannot contain the character '.", e.message
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
test "interpolate in attribute name" do
|
|
45
|
-
assert_equal "<a data-safe-foo>",
|
|
46
|
-
render("<a data-<%= value %>-foo>", locals: { value: "safe" })
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
test "interpolate in attribute name with unsafe value with spaces" do
|
|
50
|
-
e = assert_raises(BetterHtml::UnsafeHtmlError) do
|
|
51
|
-
render("<a data-<%= value %>-foo>", locals: { value: "un safe" })
|
|
52
|
-
end
|
|
53
|
-
assert_equal "Detected invalid characters as part of the interpolation "\
|
|
54
|
-
"into a attribute name around 'data-<%= value %>'.", e.message
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
test "interpolate in attribute name with unsafe value with equal sign" do
|
|
58
|
-
e = assert_raises(BetterHtml::UnsafeHtmlError) do
|
|
59
|
-
render("<a data-<%= value %>-foo>", locals: { value: "un=safe" })
|
|
60
|
-
end
|
|
61
|
-
assert_equal "Detected invalid characters as part of the "\
|
|
62
|
-
"interpolation into a attribute name around 'data-<%= value %>'.", e.message
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
test "interpolate in attribute name with unsafe value with quote" do
|
|
66
|
-
e = assert_raises(BetterHtml::UnsafeHtmlError) do
|
|
67
|
-
render("<a data-<%= value %>-foo>", locals: { value: "un\"safe" })
|
|
68
|
-
end
|
|
69
|
-
assert_equal "Detected invalid characters as part of the "\
|
|
70
|
-
"interpolation into a attribute name around 'data-<%= value %>'.", e.message
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
test "interpolate after an attribute name without a value" do
|
|
74
|
-
assert_equal '<a data-foo foo="bar">',
|
|
75
|
-
render("<a data-foo <%= html_attributes(foo: 'bar') %>>")
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
test "interpolate after an attribute name with equal sign" do
|
|
79
|
-
config = build_config(allow_unquoted_attributes: true)
|
|
80
|
-
e = assert_raises(BetterHtml::DontInterpolateHere) do
|
|
81
|
-
render("<a data-foo= <%= html_attributes(foo: 'bar') %>>", config: config)
|
|
82
|
-
end
|
|
83
|
-
assert_equal "Do not interpolate without quotes after "\
|
|
84
|
-
"attribute around 'data-foo=<%= html_attributes(foo: 'bar') %>'.", e.message
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
test "interpolate after an attribute value" do
|
|
88
|
-
e = assert_raises(BetterHtml::DontInterpolateHere) do
|
|
89
|
-
render("<a foo=\"xx\"<%= html_attributes(foo: 'bar') %>>")
|
|
90
|
-
end
|
|
91
|
-
assert_equal "Add a space after this attribute value. "\
|
|
92
|
-
"Instead of <a foo=\"xx\"<%= html_attributes(foo: 'bar') %>>"\
|
|
93
|
-
" try <a foo=\"xx\" <%= html_attributes(foo: 'bar') %>>.", e.message
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
test "interpolate in attribute without quotes" do
|
|
97
|
-
config = build_config(allow_unquoted_attributes: true)
|
|
98
|
-
e = assert_raises(BetterHtml::DontInterpolateHere) do
|
|
99
|
-
render("<a href=<%= value %>>", config: config, locals: { value: "un safe" })
|
|
100
|
-
end
|
|
101
|
-
assert_equal "Do not interpolate without quotes after "\
|
|
102
|
-
"attribute around 'href=<%= value %>'.", e.message
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
test "interpolate in attribute after value" do
|
|
106
|
-
config = build_config(allow_unquoted_attributes: true)
|
|
107
|
-
e = assert_raises(BetterHtml::DontInterpolateHere) do
|
|
108
|
-
render("<a href=something<%= value %>>", config: config, locals: { value: "" })
|
|
109
|
-
end
|
|
110
|
-
assert_equal "Do not interpolate without quotes around this "\
|
|
111
|
-
"attribute value. Instead of <a href=something<%= value %>> "\
|
|
112
|
-
"try <a href=\"something<%= value %>\">.", e.message
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
test "interpolate in tag name" do
|
|
116
|
-
assert_equal "<tag-safe-foo>",
|
|
117
|
-
render("<tag-<%= value %>-foo>", locals: { value: "safe" })
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
test "interpolate in tag name with space" do
|
|
121
|
-
e = assert_raises(BetterHtml::UnsafeHtmlError) do
|
|
122
|
-
render("<tag-<%= value %>-foo>", locals: { value: "un safe" })
|
|
123
|
-
end
|
|
124
|
-
assert_equal "Detected invalid characters as part of the interpolation "\
|
|
125
|
-
"into a tag name around: <tag-<%= value %>>.", e.message
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
test "interpolate in tag name with slash" do
|
|
129
|
-
e = assert_raises(BetterHtml::UnsafeHtmlError) do
|
|
130
|
-
render("<tag-<%= value %>-foo>", locals: { value: "un/safe" })
|
|
131
|
-
end
|
|
132
|
-
assert_equal "Detected invalid characters as part of the interpolation "\
|
|
133
|
-
"into a tag name around: <tag-<%= value %>>.", e.message
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
test "interpolate in tag name with end of tag" do
|
|
137
|
-
e = assert_raises(BetterHtml::UnsafeHtmlError) do
|
|
138
|
-
render("<tag-<%= value %>-foo>", locals: { value: "><script>" })
|
|
139
|
-
end
|
|
140
|
-
assert_equal "Detected invalid characters as part of the interpolation "\
|
|
141
|
-
"into a tag name around: <tag-<%= value %>>.", e.message
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
test "interpolate in comment" do
|
|
145
|
-
assert_equal "<!-- safe -->",
|
|
146
|
-
render("<!-- <%= value %> -->", locals: { value: "safe" })
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
test "interpolate in comment with end-of-comment" do
|
|
150
|
-
e = assert_raises(BetterHtml::UnsafeHtmlError) do
|
|
151
|
-
render("<!-- <%= value %> -->", locals: { value: "-->".html_safe })
|
|
152
|
-
end
|
|
153
|
-
assert_equal "Detected invalid characters as part of the interpolation "\
|
|
154
|
-
"into a html comment around: <!-- <%= value %>.", e.message
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
test "non html_safe interpolation into comment tag" do
|
|
158
|
-
assert_equal "<!-- --> -->",
|
|
159
|
-
render("<!-- <%= value %> -->", locals: { value: '-->' })
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
test "interpolate in script tag" do
|
|
163
|
-
assert_equal "<script> foo safe bar<script>",
|
|
164
|
-
render("<script> foo <%= value %> bar<script>", locals: { value: "safe" })
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
test "interpolate in script tag with start of comment" do
|
|
168
|
-
skip "skip for now; causing problems"
|
|
169
|
-
e = assert_raises(BetterHtml::UnsafeHtmlError) do
|
|
170
|
-
render("<script> foo <%= value %> bar<script>", locals: { value: "<!--".html_safe })
|
|
171
|
-
end
|
|
172
|
-
assert_equal "Detected invalid characters as part of the interpolation "\
|
|
173
|
-
"into a script tag around: <script> foo <%= value %>. "\
|
|
174
|
-
"A script tag cannot contain <script or </script anywhere inside of it.", e.message
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
test "interpolate in script tag with start of script" do
|
|
178
|
-
e = assert_raises(BetterHtml::UnsafeHtmlError) do
|
|
179
|
-
render("<script> foo <%= value %> bar<script>", locals: { value: "<script".html_safe })
|
|
180
|
-
end
|
|
181
|
-
assert_equal "Detected invalid characters as part of the interpolation "\
|
|
182
|
-
"into a script tag around: <script> foo <%= value %>. "\
|
|
183
|
-
"A script tag cannot contain <script or </script anywhere inside of it.", e.message
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
test "interpolate in script tag with raw interpolation" do
|
|
187
|
-
assert_equal "<script> x = \"foo\" </script>",
|
|
188
|
-
render("<script> x = <%== value %> </script>", locals: { value: JSON.dump("foo") })
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
test "interpolate in script tag with start of script case insensitive" do
|
|
192
|
-
e = assert_raises(BetterHtml::UnsafeHtmlError) do
|
|
193
|
-
render("<script> foo <%= value %> bar<script>", locals: { value: "<ScRIpT".html_safe })
|
|
194
|
-
end
|
|
195
|
-
assert_equal "Detected invalid characters as part of the interpolation "\
|
|
196
|
-
"into a script tag around: <script> foo <%= value %>. "\
|
|
197
|
-
"A script tag cannot contain <script or </script anywhere inside of it.", e.message
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
test "interpolate in script tag with end of script" do
|
|
201
|
-
e = assert_raises(BetterHtml::UnsafeHtmlError) do
|
|
202
|
-
render("<script> foo <%= value %> bar<script>", locals: { value: "</script".html_safe })
|
|
203
|
-
end
|
|
204
|
-
assert_equal "Detected invalid characters as part of the interpolation "\
|
|
205
|
-
"into a script tag around: <script> foo <%= value %>. "\
|
|
206
|
-
"A script tag cannot contain <script or </script anywhere inside of it.", e.message
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
test "interpolate html_attributes" do
|
|
210
|
-
assert_equal "<a foo=\"bar\">",
|
|
211
|
-
render("<a <%= html_attributes(foo: 'bar') %>>")
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
test "interpolate without html_attributes" do
|
|
215
|
-
e = assert_raises(BetterHtml::DontInterpolateHere) do
|
|
216
|
-
render("<a <%= 'foo=\"bar\"' %>>")
|
|
217
|
-
end
|
|
218
|
-
assert_equal "Do not interpolate String in a tag. Instead "\
|
|
219
|
-
"of <a <%= 'foo=\"bar\"' %>> please try <a <%= html_attributes(attr: value) %>>.", e.message
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
test "non html_safe interpolation into rawtext tag" do
|
|
223
|
-
assert_equal "<title></title></title>",
|
|
224
|
-
render("<title><%= value %></title>", locals: { value: '</title>' })
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
test "html_safe interpolation into rawtext tag" do
|
|
228
|
-
assert_equal "<title><safe></title>",
|
|
229
|
-
render("<title><%= value %></title>", locals: { value: '<safe>'.html_safe })
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
test "html_safe interpolation terminating the current tag" do
|
|
233
|
-
e = assert_raises(BetterHtml::UnsafeHtmlError) do
|
|
234
|
-
render("<title><%= value %></title>", locals: { value: '</title>'.html_safe })
|
|
235
|
-
end
|
|
236
|
-
assert_equal "Detected invalid characters as part of the interpolation "\
|
|
237
|
-
"into a title tag around: <title><%= value %>.", e.message
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
test "interpolate block in middle of tag" do
|
|
241
|
-
e = assert_raises(BetterHtml::DontInterpolateHere) do
|
|
242
|
-
render(<<-HTML)
|
|
243
|
-
<a href="" <%= something do %>
|
|
244
|
-
foo
|
|
245
|
-
<% end %>
|
|
246
|
-
HTML
|
|
247
|
-
end
|
|
248
|
-
assert_equal "Ruby statement not allowed.\n"\
|
|
249
|
-
"In 'tag' on line 1 column 19:\n"\
|
|
250
|
-
" <a href=\"\" <%= something do %>\n"\
|
|
251
|
-
" ^^^^^^^^^^^^^^^^^^^", e.message
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
test "interpolate with output block is valid syntax" do
|
|
255
|
-
assert_nothing_raised do
|
|
256
|
-
render(<<-HTML)
|
|
257
|
-
<%= capture do %>
|
|
258
|
-
<foo>
|
|
259
|
-
<% end %>
|
|
260
|
-
HTML
|
|
261
|
-
end
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
test "interpolate with statement block is valid syntax" do
|
|
265
|
-
assert_nothing_raised do
|
|
266
|
-
render(<<-HTML)
|
|
267
|
-
<% capture do %>
|
|
268
|
-
<foo>
|
|
269
|
-
<% end %>
|
|
270
|
-
HTML
|
|
271
|
-
end
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
test "can interpolate method calls without parenthesis" do
|
|
275
|
-
assert_equal "<div>foo</div>",
|
|
276
|
-
render("<div><%= send 'value' %></div>", locals: { value: 'foo' })
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
test "tag names are validated against tag_name_pattern regexp" do
|
|
280
|
-
e = assert_raises(BetterHtml::HtmlError) do
|
|
281
|
-
render("<foo~bar></foo~bar>")
|
|
282
|
-
end
|
|
283
|
-
assert_equal "Invalid tag name \"foo~bar\" does not match regular expression /\\A[a-z0-9\\-\\:]+\\z/\n"\
|
|
284
|
-
"On line 1 column 1:\n"\
|
|
285
|
-
"<foo~bar></foo~bar>\n"\
|
|
286
|
-
" ^^^^^^^", e.message
|
|
287
|
-
end
|
|
288
|
-
|
|
289
|
-
test "attribute names are validated against attribute_name_pattern regexp" do
|
|
290
|
-
e = assert_raises(BetterHtml::HtmlError) do
|
|
291
|
-
render("<foo bar_baz=\"1\">")
|
|
292
|
-
end
|
|
293
|
-
assert_equal "Invalid attribute name \"bar_baz\" does not match regular expression #{build_config.partial_attribute_name_pattern.inspect}\n"\
|
|
294
|
-
"On line 1 column 5:\n"\
|
|
295
|
-
"<foo bar_baz=\"1\">\n"\
|
|
296
|
-
" ^^^^^^^", e.message
|
|
297
|
-
end
|
|
298
|
-
|
|
299
|
-
test "single quotes are disallowed when allow_single_quoted_attributes=false" do
|
|
300
|
-
config = build_config(allow_single_quoted_attributes: false)
|
|
301
|
-
e = assert_raises(BetterHtml::HtmlError) do
|
|
302
|
-
render("<foo bar='1'>", config: config)
|
|
303
|
-
end
|
|
304
|
-
assert_equal "Single-quoted attributes are not allowed\n"\
|
|
305
|
-
"On line 1 column 9:\n"\
|
|
306
|
-
"<foo bar='1'>\n"\
|
|
307
|
-
" ^", e.message
|
|
308
|
-
end
|
|
309
|
-
|
|
310
|
-
test "single quotes are allowed when allow_single_quoted_attributes=true" do
|
|
311
|
-
config = build_config(allow_single_quoted_attributes: true)
|
|
312
|
-
assert_nothing_raised do
|
|
313
|
-
render("<foo bar='1'>", config: config)
|
|
314
|
-
end
|
|
315
|
-
end
|
|
316
|
-
|
|
317
|
-
test "unquoted values are disallowed when allow_unquoted_attributes=false" do
|
|
318
|
-
config = build_config(allow_unquoted_attributes: false)
|
|
319
|
-
e = assert_raises(BetterHtml::HtmlError) do
|
|
320
|
-
render("<foo bar=1>", config: config)
|
|
321
|
-
end
|
|
322
|
-
assert_equal "Unquoted attribute values are not allowed\n"\
|
|
323
|
-
"On line 1 column 9:\n"\
|
|
324
|
-
"<foo bar=1>\n"\
|
|
325
|
-
" ^", e.message
|
|
326
|
-
end
|
|
327
|
-
|
|
328
|
-
test "unquoted values are allowed when allow_unquoted_attributes=true" do
|
|
329
|
-
config = build_config(allow_unquoted_attributes: true)
|
|
330
|
-
assert_nothing_raised do
|
|
331
|
-
render("<foo bar=1>", config: config)
|
|
332
|
-
end
|
|
333
|
-
end
|
|
334
|
-
|
|
335
|
-
test "capture works as intended" do
|
|
336
|
-
output = render(<<-HTML)
|
|
337
|
-
<%- foo = capture do -%>
|
|
338
|
-
<foo>
|
|
339
|
-
<%- end -%>
|
|
340
|
-
<bar><%= foo %></bar>
|
|
341
|
-
HTML
|
|
342
|
-
|
|
343
|
-
assert_equal " <bar> <foo>\n</bar>\n", output
|
|
344
|
-
end
|
|
345
|
-
|
|
346
|
-
test "validate! raises when tag is not terminated at end of document" do
|
|
347
|
-
document = compile("<foo")
|
|
348
|
-
e = assert_raises(BetterHtml::HtmlError) do
|
|
349
|
-
document.validate!
|
|
350
|
-
end
|
|
351
|
-
assert_equal "Detected an open tag at the end of this document.", e.message
|
|
352
|
-
end
|
|
353
|
-
|
|
354
|
-
test "validate! raises when rawtext tag is not terminated at end of document" do
|
|
355
|
-
document = compile("<script>")
|
|
356
|
-
e = assert_raises(BetterHtml::HtmlError) do
|
|
357
|
-
document.validate!
|
|
358
|
-
end
|
|
359
|
-
assert_equal "Detected an open tag at the end of this document.", e.message
|
|
360
|
-
end
|
|
361
|
-
|
|
362
|
-
test "validate! raises parsing error for attribute name" do
|
|
363
|
-
document = compile("<foo bar~baz=\"1\">")
|
|
364
|
-
e = assert_raises(BetterHtml::HtmlError) do
|
|
365
|
-
document.validate!
|
|
366
|
-
end
|
|
367
|
-
assert_equal "expected whitespace, '>', attribute name or value\n"\
|
|
368
|
-
"On line 1 column 8:\n"\
|
|
369
|
-
"<foo bar~baz=\"1\">\n"\
|
|
370
|
-
" ^^^^^^^^^", e.message
|
|
371
|
-
end
|
|
372
|
-
|
|
373
|
-
private
|
|
374
|
-
|
|
375
|
-
class ViewContext < OpenStruct
|
|
376
|
-
include(ActionView::Helpers)
|
|
377
|
-
include(BetterHtml::Helpers)
|
|
378
|
-
attr_accessor :output_buffer
|
|
379
|
-
|
|
380
|
-
def get_binding
|
|
381
|
-
binding
|
|
382
|
-
end
|
|
383
|
-
end
|
|
384
|
-
|
|
385
|
-
def build_config(**options)
|
|
386
|
-
BetterHtml::Config.new(**options)
|
|
387
|
-
end
|
|
388
|
-
|
|
389
|
-
def render(source, config: build_config, locals: {})
|
|
390
|
-
context = ViewContext.new(locals)
|
|
391
|
-
impl = compile(source, config: config)
|
|
392
|
-
if ActionView.version < Gem::Version.new("5.1")
|
|
393
|
-
impl.result(context.get_binding)
|
|
394
|
-
else
|
|
395
|
-
impl.evaluate(context)
|
|
396
|
-
end
|
|
397
|
-
end
|
|
398
|
-
|
|
399
|
-
def compile(source, config: build_config)
|
|
400
|
-
if ActionView.version < Gem::Version.new("5.1")
|
|
401
|
-
BetterHtml::BetterErb::ErubisImplementation.new(source, config: config)
|
|
402
|
-
else
|
|
403
|
-
BetterHtml::BetterErb::ErubiImplementation.new(source, config: config)
|
|
404
|
-
end
|
|
405
|
-
end
|
|
406
|
-
end
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
require 'test_helper'
|
|
2
|
-
|
|
3
|
-
class BetterHtml::HelpersTest < ActiveSupport::TestCase
|
|
4
|
-
include BetterHtml::Helpers
|
|
5
|
-
|
|
6
|
-
test "html_attributes return a HtmlAttributes object" do
|
|
7
|
-
assert_equal BetterHtml::HtmlAttributes, html_attributes(foo: "bar").class
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
test "html_attributes are formatted as string" do
|
|
11
|
-
assert_equal 'foo="bar" baz="qux"',
|
|
12
|
-
html_attributes(foo: "bar", baz: "qux").to_s
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
test "html_attributes keys cannot contain invalid characters" do
|
|
16
|
-
e = assert_raises(ArgumentError) do
|
|
17
|
-
html_attributes("invalid key": "bar", baz: "qux").to_s
|
|
18
|
-
end
|
|
19
|
-
assert_equal "Attribute names must match the pattern /\\A[a-zA-Z0-9\\-\\:]+\\z/", e.message
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
test "#html_attributes does not accept incorrectly escaped html_safe values" do
|
|
23
|
-
e = assert_raises(ArgumentError) do
|
|
24
|
-
html_attributes('something': 'with "> double quote'.html_safe).to_s
|
|
25
|
-
end
|
|
26
|
-
assert_equal "The value provided for attribute 'something' contains a `\"` character which is not allowed. "\
|
|
27
|
-
"Did you call .html_safe without properly escaping this data?", e.message
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
test "#html_attributes accepts correctly escaped html_safe values" do
|
|
31
|
-
assert_equal 'something="with "> double quote"',
|
|
32
|
-
html_attributes('something': CGI.escapeHTML('with "> double quote').html_safe).to_s
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
test "#html_attributes escapes non-html_safe values" do
|
|
36
|
-
assert_equal 'something="with "> double quote"',
|
|
37
|
-
html_attributes('something': 'with "> double quote').to_s
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
test "#html_attributes accepts nil values as value-less attributes" do
|
|
41
|
-
assert_equal 'data-thing data-other-thing',
|
|
42
|
-
html_attributes('data-thing': nil, 'data-other-thing': nil).to_s
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
test "#html_attributes empty string value is output" do
|
|
46
|
-
assert_equal 'data-thing="" data-other-thing=""',
|
|
47
|
-
html_attributes('data-thing': "", 'data-other-thing': "").to_s
|
|
48
|
-
end
|
|
49
|
-
end
|