better_html 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,10 +1,8 @@
1
- require_relative 'safety_tester_base'
1
+ require 'better_html/test_helper/safety_error'
2
2
 
3
3
  module BetterHtml
4
4
  module TestHelper
5
5
  module SafeLodashTester
6
- include SafetyTesterBase
7
-
8
6
  SAFETY_TIPS = <<-EOF
9
7
  -----------
10
8
 
@@ -32,7 +30,11 @@ EOF
32
30
 
33
31
  message = ""
34
32
  tester.errors.each do |error|
35
- message << format_safety_error(data, error)
33
+ message << <<~EOL
34
+ On line #{error.location.line}
35
+ #{error.message}
36
+ #{error.location.line_source_with_underline}\n
37
+ EOL
36
38
  end
37
39
 
38
40
  message << SAFETY_TIPS
@@ -52,8 +54,8 @@ EOF
52
54
  validate!
53
55
  end
54
56
 
55
- def add_error(token, message)
56
- @errors.add(SafetyTesterBase::SafetyError.new(token, message))
57
+ def add_error(message, location:)
58
+ @errors.add(SafetyError.new(message, location: location))
57
59
  end
58
60
 
59
61
  def validate!
@@ -63,8 +65,10 @@ EOF
63
65
  validate_element(node)
64
66
 
65
67
  if node.name == 'script' && !node.closing?
66
- add_error(node.name_parts.first,
67
- "No script tags allowed nested in lodash templates")
68
+ add_error(
69
+ "No script tags allowed nested in lodash templates",
70
+ location: node.name_parts.first.location
71
+ )
68
72
  end
69
73
  when BetterHtml::NodeIterator::CData, BetterHtml::NodeIterator::Comment
70
74
  validate_no_statements(node)
@@ -85,7 +89,10 @@ EOF
85
89
  when :expr_literal
86
90
  validate_tag_expression(element, attribute.name, token)
87
91
  when :expr_escaped
88
- add_error(token, "lodash interpolation with '[%!' inside html attribute is never safe")
92
+ add_error(
93
+ "lodash interpolation with '[%!' inside html attribute is never safe",
94
+ location: token.location
95
+ )
89
96
  end
90
97
  end
91
98
  end
@@ -93,8 +100,11 @@ EOF
93
100
 
94
101
  def validate_tag_expression(node, attr_name, value_token)
95
102
  if javascript_attribute_name?(attr_name) && !lodash_safe_javascript_expression?(value_token.code.strip)
96
- add_error(value_token, "lodash interpolation in javascript attribute "\
97
- "`#{attr_name}` must call `JSON.stringify(#{value_token.code.strip})`")
103
+ add_error(
104
+ "lodash interpolation in javascript attribute "\
105
+ "`#{attr_name}` must call `JSON.stringify(#{value_token.code.strip})`",
106
+ location: value_token.location
107
+ )
98
108
  end
99
109
  end
100
110
 
@@ -113,7 +123,10 @@ EOF
113
123
  end
114
124
 
115
125
  def add_no_statement_error(node, token)
116
- add_error(token, "javascript statement not allowed here; did you mean '[%=' ?")
126
+ add_error(
127
+ "javascript statement not allowed here; did you mean '[%=' ?",
128
+ location: token.location
129
+ )
117
130
  end
118
131
  end
119
132
  end
@@ -0,0 +1,12 @@
1
+ module BetterHtml
2
+ module TestHelper
3
+ class SafetyError < InterpolatorError
4
+ attr_reader :location
5
+
6
+ def initialize(message, location:)
7
+ @location = location
8
+ super(message)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -1,3 +1,3 @@
1
1
  module BetterHtml
2
- VERSION = "0.0.8"
2
+ VERSION = "0.0.9"
3
3
  end
@@ -0,0 +1,36 @@
1
+ require 'test_helper'
2
+ require 'better_html/test_helper/safe_erb_tester'
3
+
4
+ module BetterHtml
5
+ class NodeIterator
6
+ class LocationTest < ActiveSupport::TestCase
7
+ test "location without line and column" do
8
+ loc = Location.new("foo\nbar\nbaz", 9, 10)
9
+
10
+ assert_equal "a", loc.source
11
+ assert_equal 3, loc.line
12
+ assert_equal 1, loc.column
13
+ end
14
+
15
+ test "line_source_with_underline" do
16
+ loc = Location.new("ui_helper(foo)", 10, 13)
17
+
18
+ assert_equal "foo", loc.source
19
+ assert_equal <<~EOL.strip, loc.line_source_with_underline
20
+ ui_helper(foo)
21
+ ^^^
22
+ EOL
23
+ end
24
+
25
+ test "line_source_with_underline removes empty spaces" do
26
+ loc = Location.new(" \t ui_helper(foo)", 17, 20)
27
+
28
+ assert_equal "foo", loc.source
29
+ assert_equal <<~EOL.strip, loc.line_source_with_underline
30
+ ui_helper(foo)
31
+ ^^^
32
+ EOL
33
+ end
34
+ end
35
+ end
36
+ end
@@ -5,201 +5,278 @@ module BetterHtml
5
5
  module TestHelper
6
6
  class RubyExprTest < ActiveSupport::TestCase
7
7
  test "simple call" do
8
- expr = BetterHtml::TestHelper::RubyExpr.new(code: "foo")
8
+ expr = BetterHtml::TestHelper::RubyExpr.parse("foo")
9
9
  assert_equal 1, expr.calls.size
10
10
  assert_nil expr.calls.first.instance
11
- assert_equal "foo", expr.calls.first.method
12
- assert_nil expr.calls.first.arguments
11
+ assert_equal :foo, expr.calls.first.method
12
+ assert_equal [], expr.calls.first.arguments
13
+ refute_predicate expr, :static_value?
13
14
  end
14
15
 
15
16
  test "instance call" do
16
- expr = BetterHtml::TestHelper::RubyExpr.new(code: "foo.bar")
17
+ expr = BetterHtml::TestHelper::RubyExpr.parse("foo.bar")
17
18
  assert_equal 1, expr.calls.size
18
- assert_equal [:vcall, [:@ident, "foo", [1, 0]]], expr.calls.first.instance
19
- assert_equal "bar", expr.calls.first.method
20
- assert_nil expr.calls.first.arguments
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?
21
23
  end
22
24
 
23
25
  test "instance call with arguments" do
24
- expr = BetterHtml::TestHelper::RubyExpr.new(code: "foo(x).bar")
26
+ expr = BetterHtml::TestHelper::RubyExpr.parse("foo(x).bar")
25
27
  assert_equal 1, expr.calls.size
26
- assert_equal [:method_add_arg, [:fcall, [:@ident, "foo", [1, 0]]], [:arg_paren, [:args_add_block, [[:vcall, [:@ident, "x", [1, 4]]]], false]]], expr.calls.first.instance
27
- assert_equal "bar", expr.calls.first.method
28
- assert_nil expr.calls.first.arguments
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?
29
32
  end
30
33
 
31
34
  test "instance call with parenthesis" do
32
- expr = BetterHtml::TestHelper::RubyExpr.new(code: "(foo).bar")
35
+ expr = BetterHtml::TestHelper::RubyExpr.parse("(foo).bar")
33
36
  assert_equal 1, expr.calls.size
34
- assert_equal [:paren, [[:vcall, [:@ident, "foo", [1, 1]]]]], expr.calls.first.instance
35
- assert_equal "bar", expr.calls.first.method
36
- assert_nil expr.calls.first.arguments
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?
37
41
  end
38
42
 
39
43
  test "instance call with parenthesis 2" do
40
- expr = BetterHtml::TestHelper::RubyExpr.new(code: "(foo)")
44
+ expr = BetterHtml::TestHelper::RubyExpr.parse("(foo)")
41
45
  assert_equal 1, expr.calls.size
42
46
  assert_nil expr.calls.first.instance
43
- assert_equal "foo", expr.calls.first.method
44
- assert_nil expr.calls.first.arguments
47
+ assert_equal :foo, expr.calls.first.method
48
+ assert_equal [], expr.calls.first.arguments
49
+ refute_predicate expr, :static_value?
45
50
  end
46
51
 
47
52
  test "command call" do
48
- expr = BetterHtml::TestHelper::RubyExpr.new(code: "foo bar")
53
+ expr = BetterHtml::TestHelper::RubyExpr.parse("foo bar")
49
54
  assert_equal 1, expr.calls.size
50
55
  assert_nil expr.calls.first.instance
51
- assert_equal "foo", expr.calls.first.method
52
- assert_equal [[:vcall, [:@ident, "bar", [1, 4]]]], expr.calls.first.arguments
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?
53
59
  end
54
60
 
55
61
  test "command call with block" do
56
- expr = BetterHtml::TestHelper::RubyExpr.new(code: "foo bar do")
62
+ expr = BetterHtml::TestHelper::RubyExpr.parse("foo bar do")
57
63
  assert_equal 1, expr.calls.size
58
64
  assert_nil expr.calls.first.instance
59
- assert_equal "foo", expr.calls.first.method
60
- assert_equal [[:vcall, [:@ident, "bar", [1, 4]]]], expr.calls.first.arguments
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?
61
68
  end
62
69
 
63
70
  test "call with parameters" do
64
- expr = BetterHtml::TestHelper::RubyExpr.new(code: "foo(bar)")
71
+ expr = BetterHtml::TestHelper::RubyExpr.parse("foo(bar)")
65
72
  assert_equal 1, expr.calls.size
66
73
  assert_nil expr.calls.first.instance
67
- assert_equal "foo", expr.calls.first.method
68
- assert_equal [[:vcall, [:@ident, "bar", [1, 4]]]], expr.calls.first.arguments
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?
69
77
  end
70
78
 
71
79
  test "instance call with parameters" do
72
- expr = BetterHtml::TestHelper::RubyExpr.new(code: "foo.bar(baz, x)")
80
+ expr = BetterHtml::TestHelper::RubyExpr.parse("foo.bar(baz, x)")
73
81
  assert_equal 1, expr.calls.size
74
- assert_equal [:vcall, [:@ident, "foo", [1, 0]]], expr.calls.first.instance
75
- assert_equal "bar", expr.calls.first.method
76
- assert_equal [[:vcall, [:@ident, "baz", [1, 8]]], [:vcall, [:@ident, "x", [1, 13]]]], expr.calls.first.arguments
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?
77
86
  end
78
87
 
79
88
  test "call with parameters with if conditional modifier" do
80
- expr = BetterHtml::TestHelper::RubyExpr.new(code: "foo(bar) if something?")
89
+ expr = BetterHtml::TestHelper::RubyExpr.parse("foo(bar) if something?")
81
90
  assert_equal 1, expr.calls.size
82
91
  assert_nil expr.calls.first.instance
83
- assert_equal "foo", expr.calls.first.method
84
- assert_equal [[:vcall, [:@ident, "bar", [1, 4]]]], expr.calls.first.arguments
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?
85
95
  end
86
96
 
87
97
  test "call with parameters with unless conditional modifier" do
88
- expr = BetterHtml::TestHelper::RubyExpr.new(code: "foo(bar) unless something?")
98
+ expr = BetterHtml::TestHelper::RubyExpr.parse("foo(bar) unless something?")
89
99
  assert_equal 1, expr.calls.size
90
100
  assert_nil expr.calls.first.instance
91
- assert_equal "foo", expr.calls.first.method
92
- assert_equal [[:vcall, [:@ident, "bar", [1, 4]]]], expr.calls.first.arguments
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?
93
104
  end
94
105
 
95
106
  test "expression call in ternary" do
96
- expr = BetterHtml::TestHelper::RubyExpr.new(code: "something? ? foo : bar")
107
+ expr = BetterHtml::TestHelper::RubyExpr.parse("something? ? foo : bar")
97
108
  assert_equal 2, expr.calls.size
109
+ refute_predicate expr, :static_value?
98
110
 
99
- assert_nil expr.calls.first.instance
100
- assert_equal "foo", expr.calls.first.method
101
- assert_nil expr.calls.first.arguments
111
+ assert_nil expr.calls[0].instance
112
+ assert_equal :foo, expr.calls[0].method
113
+ assert_equal [], expr.calls[0].arguments
102
114
 
103
- assert_nil expr.calls.last.instance
104
- assert_equal "bar", expr.calls.last.method
105
- assert_nil expr.calls.last.arguments
115
+ assert_nil expr.calls[1].instance
116
+ assert_equal :bar, expr.calls[1].method
117
+ assert_equal [], expr.calls[1].arguments
106
118
  end
107
119
 
108
120
  test "expression call with args in ternary" do
109
- expr = BetterHtml::TestHelper::RubyExpr.new(code: "something? ? foo(x) : bar(x)")
121
+ expr = BetterHtml::TestHelper::RubyExpr.parse("something? ? foo(x) : bar(x)")
110
122
  assert_equal 2, expr.calls.size
111
123
 
112
- assert_nil expr.calls.first.instance
113
- assert_equal "foo", expr.calls.first.method
114
- assert_equal [[:vcall, [:@ident, "x", [1, 17]]]], expr.calls.first.arguments
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
115
127
 
116
- assert_nil expr.calls.last.instance
117
- assert_equal "bar", expr.calls.last.method
118
- assert_equal [[:vcall, [:@ident, "x", [1, 26]]]], expr.calls.last.arguments
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?
119
132
  end
120
133
 
121
134
  test "string without interpolation" do
122
- expr = BetterHtml::TestHelper::RubyExpr.new(code: '"foo"')
135
+ expr = BetterHtml::TestHelper::RubyExpr.parse('"foo"')
123
136
  assert_equal 0, expr.calls.size
137
+ assert_predicate expr, :static_value?
124
138
  end
125
139
 
126
140
  test "string with interpolation" do
127
- expr = BetterHtml::TestHelper::RubyExpr.new(code: '"foo #{bar}"')
141
+ expr = BetterHtml::TestHelper::RubyExpr.parse('"foo #{bar}"')
128
142
  assert_equal 1, expr.calls.size
129
143
  assert_nil expr.calls.first.instance
130
- assert_equal "bar", expr.calls.first.method
131
- assert_nil expr.calls.first.arguments
144
+ assert_equal :bar, expr.calls.first.method
145
+ assert_equal [], expr.calls.first.arguments
146
+ refute_predicate expr, :static_value?
132
147
  end
133
148
 
134
149
  test "ternary in string with interpolation" do
135
- expr = BetterHtml::TestHelper::RubyExpr.new(code: '"foo #{foo? ? bar : baz}"')
150
+ expr = BetterHtml::TestHelper::RubyExpr.parse('"foo #{foo? ? bar : baz}"')
136
151
  assert_equal 2, expr.calls.size
137
152
 
138
153
  assert_nil expr.calls.first.instance
139
- assert_equal "bar", expr.calls.first.method
140
- assert_nil expr.calls.first.arguments
154
+ assert_equal :bar, expr.calls.first.method
155
+ assert_equal [], expr.calls.first.arguments
141
156
 
142
157
  assert_nil expr.calls.last.instance
143
- assert_equal "baz", expr.calls.last.method
144
- assert_nil expr.calls.last.arguments
158
+ assert_equal :baz, expr.calls.last.method
159
+ assert_equal [], expr.calls.first.arguments
160
+ refute_predicate expr, :static_value?
145
161
  end
146
162
 
147
163
  test "assignment to variable" do
148
- expr = BetterHtml::TestHelper::RubyExpr.new(code: 'x = foo.bar')
164
+ expr = BetterHtml::TestHelper::RubyExpr.parse('x = foo.bar')
149
165
  assert_equal 1, expr.calls.size
150
- assert_equal [:vcall, [:@ident, "foo", [1, 4]]], expr.calls.first.instance
151
- assert_equal "bar", expr.calls.first.method
152
- assert_nil expr.calls.first.arguments
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?
153
170
  end
154
171
 
155
172
  test "assignment to variable with command call" do
156
- expr = BetterHtml::TestHelper::RubyExpr.new(code: 'raw x = foo.bar')
173
+ expr = BetterHtml::TestHelper::RubyExpr.parse('raw x = foo.bar')
157
174
  assert_equal 1, expr.calls.size
158
175
  assert_nil expr.calls.first.instance
159
- assert_equal "raw", expr.calls.first.method
160
- assert_equal [[:assign, [:var_field, [:@ident, "x", [1, 4]]], [:call, [:vcall, [:@ident, "foo", [1, 8]]], :".", [:@ident, "bar", [1, 12]]]]], expr.calls.first.arguments
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?
161
179
  end
162
180
 
163
181
  test "assignment with instance call" do
164
- expr = BetterHtml::TestHelper::RubyExpr.new(code: '(x = foo).bar')
182
+ expr = BetterHtml::TestHelper::RubyExpr.parse('(x = foo).bar')
165
183
  assert_equal 1, expr.calls.size
166
- assert_equal [:paren, [[:assign, [:var_field, [:@ident, "x", [1, 1]]], [:vcall, [:@ident, "foo", [1, 5]]]]]], expr.calls.first.instance
167
- assert_equal "bar", expr.calls.first.method
168
- assert_nil expr.calls.first.arguments
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?
169
188
  end
170
189
 
171
190
  test "assignment to multiple variables" do
172
- expr = BetterHtml::TestHelper::RubyExpr.new(code: 'x, y = foo.bar')
191
+ expr = BetterHtml::TestHelper::RubyExpr.parse('x, y = foo.bar')
173
192
  assert_equal 1, expr.calls.size
174
- assert_equal [:vcall, [:@ident, "foo", [1, 7]]], expr.calls.first.instance
175
- assert_equal "bar", expr.calls.first.method
176
- assert_nil expr.calls.first.arguments
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?
177
197
  end
178
198
 
179
199
  test "safe navigation operator" do
180
- expr = BetterHtml::TestHelper::RubyExpr.new(code: 'foo&.bar')
200
+ expr = BetterHtml::TestHelper::RubyExpr.parse('foo&.bar')
181
201
  assert_equal 1, expr.calls.size
182
- assert_equal [:vcall, [:@ident, "foo", [1, 0]]], expr.calls.first.instance
183
- assert_equal "bar", expr.calls.first.method
184
- assert_nil expr.calls.first.arguments
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?
185
206
  end
186
207
 
187
208
  test "instance variable" do
188
- expr = BetterHtml::TestHelper::RubyExpr.new(code: '@foo')
209
+ expr = BetterHtml::TestHelper::RubyExpr.parse('@foo')
189
210
  assert_equal 0, expr.calls.size
211
+ refute_predicate expr, :static_value?
190
212
  end
191
213
 
192
214
  test "instance method on variable" do
193
- expr = BetterHtml::TestHelper::RubyExpr.new(code: '@foo.bar')
215
+ expr = BetterHtml::TestHelper::RubyExpr.parse('@foo.bar')
194
216
  assert_equal 1, expr.calls.size
195
- assert_equal [:var_ref, [:@ivar, "@foo", [1, 0]]], expr.calls.first.instance
196
- assert_equal "bar", expr.calls.first.method
197
- assert_nil expr.calls.first.arguments
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?
198
221
  end
199
222
 
200
223
  test "index into array" do
201
- expr = BetterHtml::TestHelper::RubyExpr.new(code: 'local_assigns[:text_class] if local_assigns[:text_class]')
202
- assert_equal 0, expr.calls.size
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?
203
280
  end
204
281
  end
205
282
  end