better_html 1.0.1 → 1.0.2

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 (26) hide show
  1. checksums.yaml +4 -4
  2. data/lib/better_html/ast/iterator.rb +3 -3
  3. data/lib/better_html/ast/node.rb +6 -2
  4. data/lib/better_html/errors.rb +2 -11
  5. data/lib/better_html/test_helper/ruby_node.rb +103 -0
  6. data/lib/better_html/test_helper/safe_erb/allowed_script_type.rb +29 -0
  7. data/lib/better_html/test_helper/safe_erb/base.rb +56 -0
  8. data/lib/better_html/test_helper/safe_erb/no_javascript_tag_helper.rb +34 -0
  9. data/lib/better_html/test_helper/safe_erb/no_statements.rb +40 -0
  10. data/lib/better_html/test_helper/safe_erb/script_interpolation.rb +65 -0
  11. data/lib/better_html/test_helper/safe_erb/tag_interpolation.rb +163 -0
  12. data/lib/better_html/test_helper/safe_erb_tester.rb +32 -285
  13. data/lib/better_html/tokenizer/location.rb +1 -1
  14. data/lib/better_html/version.rb +1 -1
  15. data/test/better_html/errors_test.rb +13 -0
  16. data/test/better_html/test_helper/ruby_node_test.rb +288 -0
  17. data/test/better_html/test_helper/safe_erb/allowed_script_type_test.rb +45 -0
  18. data/test/better_html/test_helper/safe_erb/no_javascript_tag_helper_test.rb +37 -0
  19. data/test/better_html/test_helper/safe_erb/no_statements_test.rb +128 -0
  20. data/test/better_html/test_helper/safe_erb/script_interpolation_test.rb +149 -0
  21. data/test/better_html/test_helper/safe_erb/tag_interpolation_test.rb +295 -0
  22. data/test/test_helper.rb +1 -0
  23. metadata +23 -7
  24. data/lib/better_html/test_helper/ruby_expr.rb +0 -117
  25. data/test/better_html/test_helper/ruby_expr_test.rb +0 -283
  26. data/test/better_html/test_helper/safe_erb_tester_test.rb +0 -450
data/test/test_helper.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "active_support"
2
2
  require "minitest/autorun"
3
3
  require 'better_html'
4
+ require 'better_html/parser'
4
5
 
5
6
  # Filter out Minitest backtrace while allowing backtrace from other libraries
6
7
  # to be shown.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: better_html
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Francois Chagnon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-10 00:00:00.000000000 Z
11
+ date: 2018-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ast
@@ -146,7 +146,13 @@ files:
146
146
  - lib/better_html/html_attributes.rb
147
147
  - lib/better_html/parser.rb
148
148
  - lib/better_html/railtie.rb
149
- - lib/better_html/test_helper/ruby_expr.rb
149
+ - lib/better_html/test_helper/ruby_node.rb
150
+ - lib/better_html/test_helper/safe_erb/allowed_script_type.rb
151
+ - lib/better_html/test_helper/safe_erb/base.rb
152
+ - lib/better_html/test_helper/safe_erb/no_javascript_tag_helper.rb
153
+ - lib/better_html/test_helper/safe_erb/no_statements.rb
154
+ - lib/better_html/test_helper/safe_erb/script_interpolation.rb
155
+ - lib/better_html/test_helper/safe_erb/tag_interpolation.rb
150
156
  - lib/better_html/test_helper/safe_erb_tester.rb
151
157
  - lib/better_html/test_helper/safe_lodash_tester.rb
152
158
  - lib/better_html/test_helper/safety_error.rb
@@ -163,10 +169,15 @@ files:
163
169
  - lib/better_html/version.rb
164
170
  - lib/tasks/better_html_tasks.rake
165
171
  - test/better_html/better_erb/implementation_test.rb
172
+ - test/better_html/errors_test.rb
166
173
  - test/better_html/helpers_test.rb
167
174
  - test/better_html/parser_test.rb
168
- - test/better_html/test_helper/ruby_expr_test.rb
169
- - test/better_html/test_helper/safe_erb_tester_test.rb
175
+ - test/better_html/test_helper/ruby_node_test.rb
176
+ - test/better_html/test_helper/safe_erb/allowed_script_type_test.rb
177
+ - test/better_html/test_helper/safe_erb/no_javascript_tag_helper_test.rb
178
+ - test/better_html/test_helper/safe_erb/no_statements_test.rb
179
+ - test/better_html/test_helper/safe_erb/script_interpolation_test.rb
180
+ - test/better_html/test_helper/safe_erb/tag_interpolation_test.rb
170
181
  - test/better_html/test_helper/safe_lodash_tester_test.rb
171
182
  - test/better_html/tokenizer/html_erb_test.rb
172
183
  - test/better_html/tokenizer/html_lodash_test.rb
@@ -269,11 +280,16 @@ test_files:
269
280
  - test/dummy/Rakefile
270
281
  - test/test_helper.rb
271
282
  - test/better_html/helpers_test.rb
283
+ - test/better_html/errors_test.rb
272
284
  - test/better_html/parser_test.rb
273
285
  - test/better_html/better_erb/implementation_test.rb
274
- - test/better_html/test_helper/safe_erb_tester_test.rb
286
+ - test/better_html/test_helper/safe_erb/script_interpolation_test.rb
287
+ - test/better_html/test_helper/safe_erb/no_javascript_tag_helper_test.rb
288
+ - test/better_html/test_helper/safe_erb/tag_interpolation_test.rb
289
+ - test/better_html/test_helper/safe_erb/no_statements_test.rb
290
+ - test/better_html/test_helper/safe_erb/allowed_script_type_test.rb
291
+ - test/better_html/test_helper/ruby_node_test.rb
275
292
  - test/better_html/test_helper/safe_lodash_tester_test.rb
276
- - test/better_html/test_helper/ruby_expr_test.rb
277
293
  - test/better_html/tokenizer/location_test.rb
278
294
  - test/better_html/tokenizer/html_lodash_test.rb
279
295
  - test/better_html/tokenizer/html_erb_test.rb
@@ -1,117 +0,0 @@
1
- require 'parser/current'
2
-
3
- module BetterHtml
4
- module TestHelper
5
- class RubyExpr
6
- BLOCK_EXPR = /\s*((\s+|\))do|\{)(\s*\|[^|]*\|)?\s*\Z/
7
-
8
- class ParseError < RuntimeError; end
9
-
10
- class MethodCall
11
- attr_accessor :instance, :method, :arguments
12
-
13
- def initialize(instance, method, arguments)
14
- @instance = instance
15
- @method = method
16
- @arguments = arguments
17
- end
18
-
19
- def self.from_ast_node(node)
20
- new(node.children[0], node.children[1], node.children[2..-1])
21
- end
22
- end
23
-
24
- def initialize(ast)
25
- raise ArgumentError, "expect first argument to be Parser::AST::Node" unless ast.is_a?(::Parser::AST::Node)
26
- @ast = ast
27
- end
28
-
29
- def self.parse(code)
30
- parser = ::Parser::CurrentRuby.new
31
- parser.diagnostics.ignore_warnings = true
32
- parser.diagnostics.all_errors_are_fatal = false
33
- parser.diagnostics.consumer = nil
34
-
35
- buf = ::Parser::Source::Buffer.new('(string)')
36
- buf.source = code.sub(BLOCK_EXPR, '')
37
- parsed = parser.parse(buf)
38
- raise ParseError, "error parsing code: #{code.inspect}" unless parsed
39
- new(parsed)
40
- end
41
-
42
- def start
43
- @ast.loc.expression.begin_pos
44
- end
45
-
46
- def end
47
- @ast.loc.expression.end_pos
48
- end
49
-
50
- def traverse(current=@ast, only: nil, &block)
51
- yield current if node_match?(current, only)
52
- each_child_node(current) do |child|
53
- traverse(child, only: only, &block)
54
- end
55
- end
56
-
57
- def each_child_node(current=@ast, only: nil, range: (0..-1))
58
- current.children[range].each do |child|
59
- if child.is_a?(::Parser::AST::Node) && node_match?(child, only)
60
- yield child
61
- end
62
- end
63
- end
64
-
65
- def node_match?(current, type)
66
- type.nil? || Array[type].flatten.include?(current.type)
67
- end
68
-
69
- STATIC_TYPES = [:str, :int, :true, :false, :nil]
70
-
71
- def each_return_value_recursive(current=@ast, only: nil, &block)
72
- case current.type
73
- when :send, :csend, :ivar, *STATIC_TYPES
74
- yield current if node_match?(current, only)
75
- when :if, :masgn, :lvasgn
76
- # first child is ignored as it does not contain return values
77
- # for example, in `foo ? x : y` we only care about x and y, not foo
78
- each_child_node(current, range: 1..-1) do |child|
79
- each_return_value_recursive(child, only: only, &block)
80
- end
81
- else
82
- each_child_node(current) do |child|
83
- each_return_value_recursive(child, only: only, &block)
84
- end
85
- end
86
- end
87
-
88
- def static_value?
89
- returns = []
90
- each_return_value_recursive do |node|
91
- returns << node
92
- end
93
- return false if returns.size == 0
94
- returns.each do |node|
95
- if STATIC_TYPES.include?(node.type)
96
- next
97
- elsif node.type == :dstr
98
- each_child_node(node) do |child|
99
- return false if child.type != :str
100
- end
101
- else
102
- return false
103
- end
104
- end
105
- true
106
- end
107
-
108
- def calls
109
- calls = []
110
- each_return_value_recursive(only: [:send, :csend]) do |node|
111
- calls << MethodCall.from_ast_node(node)
112
- end
113
- calls
114
- end
115
- end
116
- end
117
- end
@@ -1,283 +0,0 @@
1
- require 'test_helper'
2
- require 'better_html/test_helper/ruby_expr'
3
-
4
- module BetterHtml
5
- module TestHelper
6
- class RubyExprTest < ActiveSupport::TestCase
7
- test "simple call" do
8
- expr = BetterHtml::TestHelper::RubyExpr.parse("foo")
9
- assert_equal 1, expr.calls.size
10
- assert_nil expr.calls.first.instance
11
- assert_equal :foo, expr.calls.first.method
12
- assert_equal [], expr.calls.first.arguments
13
- refute_predicate expr, :static_value?
14
- end
15
-
16
- test "instance call" do
17
- expr = BetterHtml::TestHelper::RubyExpr.parse("foo.bar")
18
- assert_equal 1, expr.calls.size
19
- assert_equal 's(:send, nil, :foo)', expr.calls.first.instance.inspect
20
- assert_equal :bar, expr.calls.first.method
21
- assert_equal [], expr.calls.first.arguments
22
- refute_predicate expr, :static_value?
23
- end
24
-
25
- test "instance call with arguments" do
26
- expr = BetterHtml::TestHelper::RubyExpr.parse("foo(x).bar")
27
- assert_equal 1, expr.calls.size
28
- assert_equal "s(:send, nil, :foo,\n s(:send, nil, :x))", expr.calls.first.instance.inspect
29
- assert_equal :bar, expr.calls.first.method
30
- assert_equal [], expr.calls.first.arguments
31
- refute_predicate expr, :static_value?
32
- end
33
-
34
- test "instance call with parenthesis" do
35
- expr = BetterHtml::TestHelper::RubyExpr.parse("(foo).bar")
36
- assert_equal 1, expr.calls.size
37
- assert_equal "s(:begin,\n s(:send, nil, :foo))", expr.calls.first.instance.inspect
38
- assert_equal :bar, expr.calls.first.method
39
- assert_equal [], expr.calls.first.arguments
40
- refute_predicate expr, :static_value?
41
- end
42
-
43
- test "instance call with parenthesis 2" do
44
- expr = BetterHtml::TestHelper::RubyExpr.parse("(foo)")
45
- assert_equal 1, expr.calls.size
46
- assert_nil expr.calls.first.instance
47
- assert_equal :foo, expr.calls.first.method
48
- assert_equal [], expr.calls.first.arguments
49
- refute_predicate expr, :static_value?
50
- end
51
-
52
- test "command call" do
53
- expr = BetterHtml::TestHelper::RubyExpr.parse("foo bar")
54
- assert_equal 1, expr.calls.size
55
- assert_nil expr.calls.first.instance
56
- assert_equal :foo, expr.calls.first.method
57
- assert_equal '[s(:send, nil, :bar)]', expr.calls.first.arguments.inspect
58
- refute_predicate expr, :static_value?
59
- end
60
-
61
- test "command call with block" do
62
- expr = BetterHtml::TestHelper::RubyExpr.parse("foo bar do")
63
- assert_equal 1, expr.calls.size
64
- assert_nil expr.calls.first.instance
65
- assert_equal :foo, expr.calls.first.method
66
- assert_equal '[s(:send, nil, :bar)]', expr.calls.first.arguments.inspect
67
- refute_predicate expr, :static_value?
68
- end
69
-
70
- test "call with parameters" do
71
- expr = BetterHtml::TestHelper::RubyExpr.parse("foo(bar)")
72
- assert_equal 1, expr.calls.size
73
- assert_nil expr.calls.first.instance
74
- assert_equal :foo, expr.calls.first.method
75
- assert_equal '[s(:send, nil, :bar)]', expr.calls.first.arguments.inspect
76
- refute_predicate expr, :static_value?
77
- end
78
-
79
- test "instance call with parameters" do
80
- expr = BetterHtml::TestHelper::RubyExpr.parse("foo.bar(baz, x)")
81
- assert_equal 1, expr.calls.size
82
- assert_equal 's(:send, nil, :foo)', expr.calls.first.instance.inspect
83
- assert_equal :bar, expr.calls.first.method
84
- assert_equal '[s(:send, nil, :baz), s(:send, nil, :x)]', expr.calls.first.arguments.inspect
85
- refute_predicate expr, :static_value?
86
- end
87
-
88
- test "call with parameters with if conditional modifier" do
89
- expr = BetterHtml::TestHelper::RubyExpr.parse("foo(bar) if something?")
90
- assert_equal 1, expr.calls.size
91
- assert_nil expr.calls.first.instance
92
- assert_equal :foo, expr.calls.first.method
93
- assert_equal '[s(:send, nil, :bar)]', expr.calls.first.arguments.inspect
94
- refute_predicate expr, :static_value?
95
- end
96
-
97
- test "call with parameters with unless conditional modifier" do
98
- expr = BetterHtml::TestHelper::RubyExpr.parse("foo(bar) unless something?")
99
- assert_equal 1, expr.calls.size
100
- assert_nil expr.calls.first.instance
101
- assert_equal :foo, expr.calls.first.method
102
- assert_equal '[s(:send, nil, :bar)]', expr.calls.first.arguments.inspect
103
- refute_predicate expr, :static_value?
104
- end
105
-
106
- test "expression call in ternary" do
107
- expr = BetterHtml::TestHelper::RubyExpr.parse("something? ? foo : bar")
108
- assert_equal 2, expr.calls.size
109
- refute_predicate expr, :static_value?
110
-
111
- assert_nil expr.calls[0].instance
112
- assert_equal :foo, expr.calls[0].method
113
- assert_equal [], expr.calls[0].arguments
114
-
115
- assert_nil expr.calls[1].instance
116
- assert_equal :bar, expr.calls[1].method
117
- assert_equal [], expr.calls[1].arguments
118
- end
119
-
120
- test "expression call with args in ternary" do
121
- expr = BetterHtml::TestHelper::RubyExpr.parse("something? ? foo(x) : bar(x)")
122
- assert_equal 2, expr.calls.size
123
-
124
- assert_nil expr.calls[0].instance
125
- assert_equal :foo, expr.calls[0].method
126
- assert_equal '[s(:send, nil, :x)]', expr.calls[0].arguments.inspect
127
-
128
- assert_nil expr.calls[1].instance
129
- assert_equal :bar, expr.calls[1].method
130
- assert_equal '[s(:send, nil, :x)]', expr.calls[1].arguments.inspect
131
- refute_predicate expr, :static_value?
132
- end
133
-
134
- test "string without interpolation" do
135
- expr = BetterHtml::TestHelper::RubyExpr.parse('"foo"')
136
- assert_equal 0, expr.calls.size
137
- assert_predicate expr, :static_value?
138
- end
139
-
140
- test "string with interpolation" do
141
- expr = BetterHtml::TestHelper::RubyExpr.parse('"foo #{bar}"')
142
- assert_equal 1, expr.calls.size
143
- assert_nil expr.calls.first.instance
144
- assert_equal :bar, expr.calls.first.method
145
- assert_equal [], expr.calls.first.arguments
146
- refute_predicate expr, :static_value?
147
- end
148
-
149
- test "ternary in string with interpolation" do
150
- expr = BetterHtml::TestHelper::RubyExpr.parse('"foo #{foo? ? bar : baz}"')
151
- assert_equal 2, expr.calls.size
152
-
153
- assert_nil expr.calls.first.instance
154
- assert_equal :bar, expr.calls.first.method
155
- assert_equal [], expr.calls.first.arguments
156
-
157
- assert_nil expr.calls.last.instance
158
- assert_equal :baz, expr.calls.last.method
159
- assert_equal [], expr.calls.first.arguments
160
- refute_predicate expr, :static_value?
161
- end
162
-
163
- test "assignment to variable" do
164
- expr = BetterHtml::TestHelper::RubyExpr.parse('x = foo.bar')
165
- assert_equal 1, expr.calls.size
166
- assert_equal 's(:send, nil, :foo)', expr.calls.first.instance.inspect
167
- assert_equal :bar, expr.calls.first.method
168
- assert_equal [], expr.calls.first.arguments
169
- refute_predicate expr, :static_value?
170
- end
171
-
172
- test "assignment to variable with command call" do
173
- expr = BetterHtml::TestHelper::RubyExpr.parse('raw x = foo.bar')
174
- assert_equal 1, expr.calls.size
175
- assert_nil expr.calls.first.instance
176
- assert_equal :raw, expr.calls.first.method
177
- assert_equal "[s(:lvasgn, :x,\n s(:send,\n s(:send, nil, :foo), :bar))]", expr.calls.first.arguments.inspect
178
- refute_predicate expr, :static_value?
179
- end
180
-
181
- test "assignment with instance call" do
182
- expr = BetterHtml::TestHelper::RubyExpr.parse('(x = foo).bar')
183
- assert_equal 1, expr.calls.size
184
- assert_equal "s(:begin,\n s(:lvasgn, :x,\n s(:send, nil, :foo)))", expr.calls.first.instance.inspect
185
- assert_equal :bar, expr.calls.first.method
186
- assert_equal [], expr.calls.first.arguments
187
- refute_predicate expr, :static_value?
188
- end
189
-
190
- test "assignment to multiple variables" do
191
- expr = BetterHtml::TestHelper::RubyExpr.parse('x, y = foo.bar')
192
- assert_equal 1, expr.calls.size
193
- assert_equal 's(:send, nil, :foo)', expr.calls.first.instance.inspect
194
- assert_equal :bar, expr.calls.first.method
195
- assert_equal [], expr.calls.first.arguments
196
- refute_predicate expr, :static_value?
197
- end
198
-
199
- test "safe navigation operator" do
200
- expr = BetterHtml::TestHelper::RubyExpr.parse('foo&.bar')
201
- assert_equal 1, expr.calls.size
202
- assert_equal 's(:send, nil, :foo)', expr.calls[0].instance.inspect
203
- assert_equal :bar, expr.calls[0].method
204
- assert_equal [], expr.calls[0].arguments
205
- refute_predicate expr, :static_value?
206
- end
207
-
208
- test "instance variable" do
209
- expr = BetterHtml::TestHelper::RubyExpr.parse('@foo')
210
- assert_equal 0, expr.calls.size
211
- refute_predicate expr, :static_value?
212
- end
213
-
214
- test "instance method on variable" do
215
- expr = BetterHtml::TestHelper::RubyExpr.parse('@foo.bar')
216
- assert_equal 1, expr.calls.size
217
- assert_equal 's(:ivar, :@foo)', expr.calls.first.instance.inspect
218
- assert_equal :bar, expr.calls.first.method
219
- assert_equal [], expr.calls.first.arguments
220
- refute_predicate expr, :static_value?
221
- end
222
-
223
- test "index into array" do
224
- expr = BetterHtml::TestHelper::RubyExpr.parse('local_assigns[:text_class] if local_assigns[:text_class]')
225
- assert_equal 1, expr.calls.size
226
- assert_equal 's(:send, nil, :local_assigns)', expr.calls.first.instance.inspect
227
- assert_equal :[], expr.calls.first.method
228
- assert_equal '[s(:sym, :text_class)]', expr.calls.first.arguments.inspect
229
- refute_predicate expr, :static_value?
230
- end
231
-
232
- test "static_value? for ivar" do
233
- expr = BetterHtml::TestHelper::RubyExpr.parse('@foo')
234
- refute_predicate expr, :static_value?
235
- end
236
-
237
- test "static_value? for str" do
238
- expr = BetterHtml::TestHelper::RubyExpr.parse("'str'")
239
- assert_predicate expr, :static_value?
240
- end
241
-
242
- test "static_value? for int" do
243
- expr = BetterHtml::TestHelper::RubyExpr.parse("1")
244
- assert_predicate expr, :static_value?
245
- end
246
-
247
- test "static_value? for bool" do
248
- expr = BetterHtml::TestHelper::RubyExpr.parse("true")
249
- assert_predicate expr, :static_value?
250
- end
251
-
252
- test "static_value? for nil" do
253
- expr = BetterHtml::TestHelper::RubyExpr.parse("nil")
254
- assert_predicate expr, :static_value?
255
- end
256
-
257
- test "static_value? for dstr without interpolate" do
258
- expr = BetterHtml::TestHelper::RubyExpr.parse('"str"')
259
- assert_predicate expr, :static_value?
260
- end
261
-
262
- test "static_value? for dstr with interpolate" do
263
- expr = BetterHtml::TestHelper::RubyExpr.parse('"str #{foo}"')
264
- refute_predicate expr, :static_value?
265
- end
266
-
267
- test "static_value? with safe ternary" do
268
- expr = BetterHtml::TestHelper::RubyExpr.parse('foo ? \'a\' : \'b\'')
269
- assert_predicate expr, :static_value?
270
- end
271
-
272
- test "static_value? with safe conditional" do
273
- expr = BetterHtml::TestHelper::RubyExpr.parse('\'foo\' if bar?')
274
- assert_predicate expr, :static_value?
275
- end
276
-
277
- test "static_value? with safe assignment" do
278
- expr = BetterHtml::TestHelper::RubyExpr.parse('x = \'foo\'')
279
- assert_predicate expr, :static_value?
280
- end
281
- end
282
- end
283
- end