seeing_is_believing 1.0.1 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -14,8 +14,8 @@ describe SeeingIsBelieving do
14
14
  let(:proving_grounds_dir) { File.expand_path '../../proving_grounds', __FILE__ }
15
15
 
16
16
  it 'takes a string or and returns a result of the line numbers (counting from 1) and each inspected result from that line' do
17
- input = "1+1\n'2'+'2'"
18
- invoke(input)[1].should == ["2"]
17
+ input = "10+10\n'2'+'2'"
18
+ invoke(input)[1].should == ["20"]
19
19
  invoke(input)[2].should == ['"22"']
20
20
  end
21
21
 
@@ -38,78 +38,25 @@ describe SeeingIsBelieving do
38
38
  end
39
39
 
40
40
  it 'records each value when a line is evaluated multiple times' do
41
- values_for("(1..2).each do |i|\ni\nend").should == [[], ['1', '2'], ['1..2']]
41
+ values_for("(1..2).each do |i|\ni\nend").should == [['1..2'], ['1', '2'], ['1..2']]
42
42
  end
43
43
 
44
+ # now that we're using Parser, there's very very few of these
44
45
  it 'evalutes to an empty array for lines that it cannot understand' do
45
- vs = values_for('if true &&
46
- if true &&
47
- true
48
- 1
49
- end
50
- 2
51
- end').should == [[], [], ['true'], ['1'], ['1'], ['2'], ['2']]
52
-
53
- values_for("[3].map do |n|\n n*2\n end").should == [[], ['6'], ['[6]']]
54
-
55
- values_for("[1].map do |n1|
56
- [2].map do |n2|
57
- n1 + n2
58
- end
59
- end").should == [[], [], ['3'], ['[3]'], ['[[3]]']]
60
-
61
- values_for("[1].map do |n1|
62
- [2].map do |n2| n1 + n2
63
- end
64
- end").should == [[], [], ['[3]'], ['[[3]]']]
65
-
66
- values_for("[1].map do |n1|
67
- [2].map do |n2|
68
- n1 + n2 end
69
- end").should == [[], [], ['[3]'], ['[[3]]']]
70
-
71
- values_for("[1].map do |n1|
72
- [2].map do |n2|
73
- n1 + n2 end end").should == [[], [], ['[[3]]']]
74
-
75
- values_for("[1].map do |n1|
76
- [2].map do |n2| n1 + n2 end end").should == [[], ['[[3]]']]
77
-
78
- values_for("[1].map do |n1| [2].map do |n2| n1 + n2 end end").should == [['[[3]]']]
79
-
80
- values_for("[1].map do |n1|
81
- [2].map do |n2|
82
- n1 + n2
83
- end end").should == [[], [], ['3'], ['[[3]]']]
84
-
85
- values_for("[1].map do |n1| [2].map do |n2|
86
- n1 + n2
87
- end end").should == [[], ['3'], ['[[3]]']]
88
-
89
- values_for("[1].map do |n1| [2].map do |n2|
90
- n1 + n2 end end").should == [[], ['[[3]]']]
91
-
92
- values_for("[1].map do |n1| [2].map do |n2|
93
- n1 + n2 end
94
- end").should == [[], [], ['[[3]]']]
95
-
96
- values_for("1 +
97
- 2").should == [[], ['3']]
98
-
46
+ values_for("[3].map \\\ndo |n|\n n*2\n end").should == [['[3]'], [], ['6'], ['[6]']]
99
47
  values_for("'\n1\n'").should == [[], [], ['"\n1\n"']]
48
+ values_for("<<HEREDOC\n\n1\nHEREDOC").should == [[%Q'"\\n1\\n"']] # newlines escaped b/c lib inspects them
49
+ values_for("<<-HEREDOC\n\n1\nHEREDOC").should == [[%Q'"\\n1\\n"']]
50
+ end
100
51
 
101
- # fails b/c parens should go around line 1, not around entire expression -.^
102
- # values_for("<<HEREDOC\n1\nHEREDOC").should == [[], [], ['"\n1\n"']]
103
- # values_for("<<-HEREDOC\n1\nHEREDOC").should == [[], [], ['"\n1\n"']]
52
+ it 'records the targets of chained methods' do
53
+ values_for("[*1..5]\n.map { |n| n * 2 }\n.take(2)\n.size").should ==
54
+ [["[1, 2, 3, 4, 5]"], ["[2, 4, 6, 8, 10]"], ["[2, 4]"], ["2"]]
104
55
  end
105
56
 
106
- it "does not record expressions that are here docs (only really b/c it's not smart enough)" do
107
- values_for("<<A\n1\nA").should be_all &:empty?
108
- values_for(" <<A\n1\nA").should be_all &:empty?
109
- values_for("<<-A\n1\n A").should be_all &:empty?
110
- values_for(" <<-A\n1\n A").should be_all &:empty?
111
- values_for("s=<<-A\n1\n A").should be_all &:empty?
112
- values_for("def meth\n<<-A\n1\nA\nend").should == [[], [], [], [], ['nil']]
57
+ it "records heredocs" do
58
+ values_for("<<A\n1\nA").should == [[%'"1\\n"']]
59
+ values_for("<<-A\n1\nA").should == [[%'"1\\n"']]
113
60
  end
114
61
 
115
62
  it 'does not insert code into the middle of heredocs' do
@@ -153,7 +100,6 @@ describe SeeingIsBelieving do
153
100
  result[2].exception.should == result.exception
154
101
 
155
102
  result[3].should == []
156
- result.to_a.size.should == 3
157
103
  end
158
104
 
159
105
  it 'records the backtrace on the errors' do
@@ -171,24 +117,29 @@ describe SeeingIsBelieving do
171
117
  meth
172
118
 
173
119
  # comment
174
- __LINE__').should == [['1'], ['2'], [], [], ['5'], ['nil'], ['5'], [], [], ['10']]
120
+ __LINE__').should == [['1'], ['2'], [], [], ['5'], [], ['5'], [], [], ['10']]
175
121
  end
176
122
 
177
- it 'does not try to record a return statement when that will break it' do
178
- values_for("def meth \n return 1 \n end \n meth").should == [[], [], ['nil'], ['1']]
179
- values_for("def meth \n return 1 if true \n end \n meth").should == [[], [], ['nil'], ['1']]
180
- values_for("def meth \n return 1 if false \n end \n meth").should == [[], [], ['nil'], ['nil']]
181
- values_for("-> { \n return 1 \n }.call" ).should == [[], [], ['1']]
182
- # this doesn't work because the return detecting code is a very conservative regexp
183
- # values_for("-> { return 1 }.call" ).should == [['1']]
123
+ it 'records return statements' do
124
+ values_for("def meth \n return 1 \n end \n meth").should == [[], ['1'], [], ['1']]
125
+ values_for("-> { \n return 1 \n }.call" ).should == [[], ['1'], ['1']]
126
+ values_for("-> { return 1 }.call" ).should == [['1']]
127
+
128
+ pending "we'd like this to record 1 and nil, but currently we dont' differentiate between inline and multiline if statements" do
129
+ values_for("def meth \n return 1 if true \n end \n meth").should == [[], ['1'], [], ['1']] # records true instead of 1
130
+ values_for("def meth \n return 1 if false \n end \n meth").should == [[], ['nil'], [], ['nil']] # records false instead of nil
131
+ end
184
132
  end
185
133
 
186
134
  it 'does not try to record the keyword next' do
187
- values_for("(1..2).each do |i|\nnext if i == 1\ni\nend").should == [[], [], ['2'], ['1..2']]
135
+ # tbh, I don't even really know what I want in this case. Maybe record nothing since there is no arg to next?
136
+ pending 'broken because of misordering in the rewriter' do
137
+ values_for("(1..2).each do |i|\nnext if i == 1\ni\nend").should == [['1..2'], [], ['true', 'false'], ['1..2']]
138
+ end
188
139
  end
189
140
 
190
141
  it 'does not try to record the keyword redo' do
191
- values_for(<<-DOC).should == [[], ['0'], [], ['1', '2', '3', '4'], [], ['0...3'], ['nil'], ['0...3']]
142
+ values_for(<<-DOC).should == [[], ['0'], ['0...3'], ['1', '2', '3', '4'], ['false', 'true', 'false', 'false'], ['0...3'], [], ['0...3']]
192
143
  def meth
193
144
  n = 0
194
145
  for i in 0...3
@@ -201,21 +152,25 @@ describe SeeingIsBelieving do
201
152
  end
202
153
 
203
154
  it 'does not try to record the keyword retry' do
204
- values_for(<<-DOC).should == [[], [], [], ['nil']]
205
- def meth
206
- rescue
207
- retry
208
- end
209
- DOC
155
+ pending 'uhhh, what do I want here?' do
156
+ values_for(<<-DOC).should == [[], [], [], ['nil']]
157
+ def meth
158
+ rescue
159
+ retry
160
+ end
161
+ DOC
162
+ end
210
163
  end
211
164
 
212
165
  it 'does not try to record the keyword retry' do
213
- values_for(<<-DOC).should == [[], ['0'], [], ['nil']]
214
- (0..2).each do |n|
215
- n
216
- break
217
- end
218
- DOC
166
+ pending 'uhhh, what do I want here?' do
167
+ values_for(<<-DOC).should == [[], ['0'], [], ['nil']]
168
+ (0..2).each do |n|
169
+ n
170
+ break
171
+ end
172
+ DOC
173
+ end
219
174
  end
220
175
 
221
176
  it 'does not affect its environment' do
@@ -260,7 +215,7 @@ describe SeeingIsBelieving do
260
215
  end
261
216
 
262
217
  it 'does not capture output from __END__ onward' do
263
- values_for("1+1\nDATA.read\n__END__\n....").should == [['2'], ['"...."']]
218
+ values_for("1+1\nDATA.read\n__END__\n....").should == [['2'], ['"....\n"']] # <-- should this actually write a newline on the end?
264
219
  end
265
220
 
266
221
  it 'raises a SyntaxError when the whole program is invalid' do
@@ -280,8 +235,9 @@ describe SeeingIsBelieving do
280
235
  end
281
236
 
282
237
  it 'can deal with methods that are invoked entirely on the next line' do
283
- values_for("a = 1\n.even?\na").should == [[], ['false'], ['false']]
284
- values_for("1\n.even?\n__END__").should == [[], ['false']]
238
+ values_for("a = 1\n.even?\na").should == [['1'], ['false'], ['false']]
239
+ values_for("a = 1.\neven?\na").should == [['1'], ['false'], ['false']]
240
+ values_for("1\n.even?\n__END__").should == [['1'], ['false']]
285
241
  end
286
242
 
287
243
  it 'does not record leading comments' do
@@ -309,7 +265,7 @@ describe SeeingIsBelieving do
309
265
 
310
266
  it "doesn't fuck up when there are lines with magic comments in the middle of the app" do
311
267
  values_for('1+1
312
- # encoding: wtf').should == [['2'], []]
268
+ # encoding: wtf').should == [['2']]
313
269
  end
314
270
 
315
271
  it "doesn't remove multiple leading comments" do
@@ -321,23 +277,23 @@ describe SeeingIsBelieving do
321
277
  "2").should == [[], ['1'], ['2']]
322
278
  end
323
279
 
324
- it 'can record the middle of a chain of calls', not_implemented: true do
280
+ it 'can record the middle of a chain of calls' do
281
+ values_for("1 +\n2").should == [['1'], ['3']]
282
+ values_for("1\\\n+ 2").should == [['1'], ['3']]
325
283
  values_for("[*1..5]
326
284
  .select(&:even?)
327
285
  .map { |n| n * 3 }").should == [['[1, 2, 3, 4, 5]'],
328
286
  ['[2, 4]'],
329
287
  ['[6, 12]']]
330
- # values_for("[*1..5]
331
- # .select(&:even)
332
- # .map { |n| n * 2 }.
333
- # map { |n| n / 2 }\
334
- # .map { |n| n * 3 }").should == [['[1, 2, 3, 4, 5]'],
335
- # ['[2, 4]'],
336
- # ['[4, 8]'],
337
- # ['[2, 4]'],
338
- # ['[6, 12]']]
339
- # values_for("1 +\n2").should == [['1'], ['3']]
340
- # values_for("1\\\n+ 2").should == [['1'], ['3']]
288
+ values_for("[*1..5]
289
+ .select(&:even?)
290
+ .map { |n| n * 2 }.
291
+ map { |n| n / 2 }\\
292
+ .map { |n| n * 3 }").should == [['[1, 2, 3, 4, 5]'],
293
+ ['[2, 4]'],
294
+ ['[4, 8]'],
295
+ ['[2, 4]'],
296
+ ['[6, 12]']]
341
297
  end
342
298
 
343
299
  context 'when given a debugger' do
@@ -347,22 +303,18 @@ describe SeeingIsBelieving do
347
303
  invoke "1", debugger: debugger
348
304
  end
349
305
 
350
- it 'prints the program without comments' do
351
- call
352
- debugger.to_s.should include "SOURCE WITHOUT COMMENTS:"
353
- debugger.to_s.should include "\n1\n"
354
- end
355
-
356
306
  it 'prints the pre-evaluated program' do
357
307
  call
358
308
  debugger.to_s.should include "TRANSLATED PROGRAM:"
359
309
  debugger.to_s.should include "\nbegin;" # there is more, but we're just interested in showing that it wound up in the stream
360
310
  end
361
311
 
362
- it 'has the ExpressionList print its debug options into the output' do
312
+ it 'prints the result', t:true do
363
313
  call
364
- debugger.to_s.should include "EXPRESSION EVALUATION:"
314
+ debugger.to_s.should include "RESULT:"
315
+ debugger.to_s.should include '1=>#<SIB:Line["1"] no exception>'
365
316
  end
317
+ # should ProgramRewriter have some debug options?
366
318
  end
367
319
 
368
320
  end
@@ -1,52 +1,6 @@
1
1
  require 'seeing_is_believing'
2
2
 
3
3
  describe SeeingIsBelieving::SyntaxAnalyzer do
4
- it 'knows if syntax is valid' do
5
- is_valid = lambda { |code| described_class.valid_ruby? code }
6
- is_valid['1+2'].should be_true
7
- is_valid['+'].should be_false
8
- is_valid["=begin\n1\n=end"].should be_true
9
-
10
- # due to what are possibly bugs in Ripper
11
- # these don't raise any errors, so have to check them explicitly
12
- is_valid["'"].should be_false
13
- is_valid["/"].should be_false
14
- is_valid["=begin"].should be_false
15
- is_valid[" =begin"].should be_false
16
- is_valid[" = begin"].should be_false
17
- is_valid["=begin\n1"].should be_false
18
- is_valid["=begin\n1\n=end\n=begin"].should be_false
19
- is_valid["=begin\n1\n=end\n=end"].should be_false
20
- end
21
-
22
- it 'knows if the expression is a heredoc' do
23
- is_here_doc = lambda { |code| described_class.here_doc? code }
24
- is_here_doc["<<A\nA"].should be_true
25
- is_here_doc["a=<<A\nabc\nA"].should be_true
26
- is_here_doc["meth(<<A)\nabc\nA"].should be_true
27
- is_here_doc["meth(<<A)\nabc\nA"].should be_true
28
- is_here_doc["meth(<<-A)\n abc\n A"].should be_true
29
- is_here_doc["meth(<<-\"a b\")\n abc\n a b"].should be_true
30
- is_here_doc["meth(<<-\"a b\", <<something)\n 1\n a b\n2\nsomething"].should be_true
31
-
32
- is_here_doc["a=<<A\nabc\nA\na"].should be_false
33
- is_here_doc["def meth\nwhateva(<<A)\nabc\nA\nend"].should be_false
34
- is_here_doc["a << b\nb"].should be_false
35
- is_here_doc["a<<b\nb"].should be_false
36
- end
37
-
38
- it 'knows if the expression is an unfinished heredoc' do
39
- is_unfinished_heredoc = lambda { |code| described_class.unfinished_here_doc? code }
40
- is_unfinished_heredoc["<<A"].should be_true
41
- is_unfinished_heredoc["puts <<A, <<B\na\nA"].should be_true
42
- is_unfinished_heredoc["<<-A\n"].should be_true
43
-
44
- is_unfinished_heredoc["puts <<A\na\nA"].should be_false
45
- is_unfinished_heredoc["puts <<-A\na\nA"].should be_false
46
- is_unfinished_heredoc["puts <<-A\na\n A"].should be_false
47
- is_unfinished_heredoc["puts <<A, <<B\na\nA\nB"].should be_false
48
- end
49
-
50
4
  it 'knows if the last line is a comment' do
51
5
  is_comment = lambda { |code| described_class.ends_in_comment? code }
52
6
 
@@ -62,6 +16,9 @@ describe SeeingIsBelieving::SyntaxAnalyzer do
62
16
  is_comment["a # whatev \n b"].should be_false
63
17
  is_comment[""].should be_false
64
18
  is_comment["=begin\n=end\n\n =end"].should be_false
19
+ pending "Fix comments to not be shit" do
20
+ is_comment[%'"\n\#{1}"'].should be_false
21
+ end
65
22
  end
66
23
 
67
24
  it 'knows if it contains an unclosed comment' do
@@ -92,278 +49,8 @@ describe SeeingIsBelieving::SyntaxAnalyzer do
92
49
  described_class.line_is_comment?('abc').should be_false
93
50
  end
94
51
 
95
- # probably don't really need this many tests, but I'm unfamiliar with how thorough Ripper is
96
- # and already found areas where it doesn't behave correctly
97
- it 'knows if the code contains an unclosed string' do
98
- is_unclosed_string = lambda { |code| described_class.unclosed_string? code }
99
- [%(a),
100
- %("a"),
101
- %("a \n"),
102
- %("a \n a"),
103
- %(a \n" a"),
104
- %(a \n' a'),
105
- %('a' "b"),
106
- %('a"b'),
107
- %("a'b"),
108
- %("a\\""),
109
- %(%()),
110
- %(%<>),
111
- %(%[]),
112
- %(%{}),
113
- %(%Q()),
114
- %(%q()),
115
- %("\#{""}"),
116
- %("\#{''}"),
117
- %("\#{%(\#{%[\#{%[]}]})}"),
118
- %(%{}),
119
- %(%<>),
120
- %(%..),
121
- ].each do |string|
122
- is_unclosed_string[string].should be_false, "Expected #{string.inspect} to be closed"
123
- end
124
-
125
- [%(a "),
126
- %(a '),
127
- %("a \n),
128
- %(a \n 'a\n),
129
- %("a"\n"b),
130
- %("a" "b),
131
- %("a" "b'),
132
- %("a\\"),
133
- %('a\\'),
134
- %(%\(),
135
- %(%<),
136
- %(%[),
137
- %(%{),
138
- %(%Q[),
139
- %(%q[),
140
- %(%Q(\#{)),
141
- %("\#{),
142
- %("\#{'}"),
143
- %("\#{"}"),
144
- %("\#{%(\#{%[\#{%[}]})}"),
145
- ].each do |string|
146
- is_unclosed_string[string].should be_true, "Expected #{string.inspect} to be unclosed"
147
- end
148
- end
149
-
150
- it 'knows if the code contains an unclosed regexp' do
151
- is_unclosed_regexp = lambda { |code| described_class.unclosed_regexp? code }
152
- [%(a),
153
- %(/a/),
154
- %(/a \n/),
155
- %(/a \n a/),
156
- %(a \n/ a/),
157
- %(/a\\//),
158
- %(/\#{//}/),
159
- %(%r()),
160
- %(%r{}),
161
- %(%r<>),
162
- %(%r..),
163
- %(/\na\nb\n/x),
164
- %(r..i),
165
- %(/\na\nb\n/xmi),
166
- ].each do |code|
167
- is_unclosed_regexp[code].should be_false, "Expected #{code.inspect} to be closed"
168
- end
169
-
170
- [%(a + /),
171
- %(/a \n),
172
- %(a \n /a\n),
173
- %(/a/\n/b),
174
- %(/a\\/),
175
- %(%r\(),
176
- %(%r<),
177
- %(%r[),
178
- %(%r{),
179
- %(%r(\#{)),
180
- %(%r[\#{),
181
- %("\#{%r[}"),
182
- ].each do |code|
183
- is_unclosed_regexp[code].should be_true, "Expected #{code.inspect} to be unclosed"
184
- end
185
- end
186
-
187
- shared_examples_for 'single line void_value_expression?' do |keyword, options={}|
188
- specify "`#{keyword}` returns true when the expression ends in #{keyword} without an argument" do
189
- described_class.void_value_expression?("#{keyword}").should be_true
190
- described_class.void_value_expression?("#{keyword} if true").should be_true
191
- described_class.void_value_expression?("o.#{keyword}").should be_false
192
- described_class.void_value_expression?(":#{keyword}").should be_false
193
- described_class.void_value_expression?(":'#{keyword}'").should be_false
194
- described_class.void_value_expression?("'#{keyword}'").should be_false
195
- described_class.void_value_expression?("def a\n#{keyword}\nend").should be_false
196
- described_class.void_value_expression?("-> {\n#{keyword}\n}").should be_false
197
- described_class.void_value_expression?("Proc.new {\n#{keyword}\n}").should be_false
198
- described_class.void_value_expression?("#{keyword}_something").should be_false
199
- described_class.void_value_expression?("'#{keyword}\n#{keyword}\n#{keyword}'").should be_false
200
-
201
- unless options[:no_args]
202
- described_class.void_value_expression?("#{keyword}(1)").should be_true
203
- described_class.void_value_expression?("#{keyword} 1").should be_true
204
- described_class.void_value_expression?("#{keyword} 1\n").should be_true
205
- described_class.void_value_expression?("#{keyword} 1 if true").should be_true
206
- described_class.void_value_expression?("#{keyword} 1 if false").should be_true
207
- described_class.void_value_expression?("def a\n#{keyword} 1\nend").should be_false
208
- described_class.void_value_expression?("-> {\n#{keyword} 1\n}").should be_false
209
- described_class.void_value_expression?("Proc.new {\n#{keyword} 1\n}").should be_false
210
- described_class.void_value_expression?("#{keyword} \\\n1").should be_true
211
- end
212
- end
213
-
214
- it "knows when an if statement ends in `#{keyword}`" do
215
- # if
216
- described_class.void_value_expression?("if true\n#{keyword}\nend").should be_true
217
- described_class.void_value_expression?("if true\n #{keyword}\nend").should be_true
218
- described_class.void_value_expression?("if true\n 1+1\n #{keyword}\nend").should be_true
219
- described_class.void_value_expression?("if true\n #{keyword}\n 1+1\n end").should be_false
220
- described_class.void_value_expression?("123 && if true\n #{keyword}\nend").should be_false
221
- described_class.void_value_expression?("def m\n if true\n #{keyword}\nend\n end").should be_false
222
- described_class.void_value_expression?("if true; #{keyword}; end").should be_true
223
- described_class.void_value_expression?("if true; 1; end").should be_false
224
-
225
- # if .. elsif
226
- described_class.void_value_expression?("if true\n #{keyword}\n elsif true\n 1\n end").should be_true
227
- described_class.void_value_expression?("if true\n 1\n elsif true\n #{keyword}\n end").should be_true
228
- described_class.void_value_expression?("if true\n #{keyword}\n 2\n elsif true\n 1\n end").should be_false
229
- described_class.void_value_expression?("if true\n 1\n elsif true\n #{keyword}\n 2\n end").should be_false
230
-
231
- # if .. else
232
- described_class.void_value_expression?("if true\n #{keyword}\n else 1\n end").should be_true
233
- described_class.void_value_expression?("if true\n 1\n else\n #{keyword}\n end").should be_true
234
- described_class.void_value_expression?("if true\n #{keyword}\n 2\n else 1\n end").should be_false
235
- described_class.void_value_expression?("if true\n 1\n else\n #{keyword}\n 2\n end").should be_false
236
-
237
- # if .. elsif .. else .. end
238
- described_class.void_value_expression?("if true\n #{keyword}\nelsif true\n 1 else 1\n end").should be_true
239
- described_class.void_value_expression?("if true\n 1\n elsif true\n #{keyword}\n else\n 1\n end").should be_true
240
- described_class.void_value_expression?("if true\n 1\n elsif true\n 1\n elsif true\n #{keyword}\n else\n 1\n end").should be_true
241
- described_class.void_value_expression?("if true\n 1\n elsif true\n 1\n else\n #{keyword}\n end").should be_true
242
- described_class.void_value_expression?("if true\n #{keyword}\n 2\nelsif true\n 1 else 1\n end").should be_false
243
- described_class.void_value_expression?("if true\n 1\n elsif true\n #{keyword}\n 2\n else\n 1\n end").should be_false
244
- described_class.void_value_expression?("if true\n 1\n elsif true\n 1\n elsif true\n #{keyword}\n 2\n else\n 1\n end").should be_false
245
- described_class.void_value_expression?("if true\n 1\n elsif true\n 1\n else\n #{keyword}\n 2\n end").should be_false
246
-
247
- unless options[:no_args]
248
- # if
249
- described_class.void_value_expression?("if true\n#{keyword} 1\nend").should be_true
250
- described_class.void_value_expression?("if true\n #{keyword} 1\nend").should be_true
251
- described_class.void_value_expression?("if true\n 1+1\n #{keyword} 1\nend").should be_true
252
- described_class.void_value_expression?("if true\n #{keyword} 1\n 1+1\n end").should be_false
253
- described_class.void_value_expression?("123 && if true\n #{keyword} 1\nend").should be_false
254
- described_class.void_value_expression?("def m\n if true\n #{keyword} 1\nend\n end").should be_false
255
- described_class.void_value_expression?("if true; #{keyword} 1; end").should be_true
256
- described_class.void_value_expression?("if true; 1; end").should be_false
257
-
258
- # if .. elsif
259
- described_class.void_value_expression?("if true\n #{keyword} 1\n elsif true\n 1\n end").should be_true
260
- described_class.void_value_expression?("if true\n 1\n elsif true\n #{keyword}\n end").should be_true
261
- described_class.void_value_expression?("if true\n #{keyword} 1\n 2\n elsif true\n 1\n end").should be_false
262
- described_class.void_value_expression?("if true\n 1\n elsif true\n #{keyword}\n 2\n end").should be_false
263
-
264
- # if .. else
265
- described_class.void_value_expression?("if true\n #{keyword} 1\n else 1\n end").should be_true
266
- described_class.void_value_expression?("if true\n 1\n else\n #{keyword}\n end").should be_true
267
- described_class.void_value_expression?("if true\n #{keyword} 1\n 2\n else 1\n end").should be_false
268
- described_class.void_value_expression?("if true\n 1\n else\n #{keyword}\n 2\n end").should be_false
269
-
270
- # if .. elsif .. else .. end
271
- described_class.void_value_expression?("if true\n #{keyword} 1\nelsif true\n 1 else 1\n end").should be_true
272
- described_class.void_value_expression?("if true\n 1\n elsif true\n #{keyword}\n else\n 1\n end").should be_true
273
- described_class.void_value_expression?("if true\n 1\n elsif true\n 1\n elsif true\n #{keyword}\n else\n 1\n end").should be_true
274
- described_class.void_value_expression?("if true\n 1\n elsif true\n 1\n else\n #{keyword}\n end").should be_true
275
- described_class.void_value_expression?("if true\n #{keyword} 1\n 2\nelsif true\n 1 else 1\n end").should be_false
276
- described_class.void_value_expression?("if true\n 1\n elsif true\n #{keyword}\n 2\n else\n 1\n end").should be_false
277
- described_class.void_value_expression?("if true\n 1\n elsif true\n 1\n elsif true\n #{keyword}\n 2\n else\n 1\n end").should be_false
278
- described_class.void_value_expression?("if true\n 1\n elsif true\n 1\n else\n #{keyword}\n 2\n end").should be_false
279
- end
280
- end
281
-
282
- it "knows when a begin statement ends in `#{keyword}`" do
283
- described_class.void_value_expression?("begin\n #{keyword}\n end").should be_true
284
- described_class.void_value_expression?("begin\n 1\n #{keyword}\n end").should be_true
285
- described_class.void_value_expression?("begin\n #{keyword}\n 1\n end").should be_false
286
- described_class.void_value_expression?("begin\n 1\n #{keyword}\n 1\n end").should be_false
287
-
288
- unless options[:no_args]
289
- described_class.void_value_expression?("begin\n #{keyword} '123' \n end").should be_true
290
- described_class.void_value_expression?("begin\n 1\n #{keyword} 456\n end").should be_true
291
- described_class.void_value_expression?("begin\n #{keyword} :'789'\n 1\n end").should be_false
292
- described_class.void_value_expression?("begin\n 1\n #{keyword} /101112/\n 1\n end").should be_false
293
- end
294
-
295
- # I don't know that the rest of these hold across all versions of Ruby since they make no fucking sense
296
- # so even though some of them can technically be non-vve,
297
- # I'm still going to call any one of them a vve
298
- #
299
- # e.g. (tested on 2.0)
300
- # this is allowed
301
- # -> { a = begin; return
302
- # rescue; return
303
- # ensure; return
304
- # end }
305
- # this is not
306
- # -> { a = begin; return
307
- # end }
308
-
309
- # with rescue...
310
- described_class.void_value_expression?("begin\n #{keyword}\n rescue\n #{keyword} end").should be_true
311
- described_class.void_value_expression?("begin\n 1\n #{keyword}\n rescue RuntimeError => e\n end").should be_true
312
- described_class.void_value_expression?("begin\n 1\n #{keyword}\n rescue RuntimeError\n end").should be_true
313
- described_class.void_value_expression?("begin\n 1\n #{keyword}\n rescue\n end").should be_true
314
- described_class.void_value_expression?("begin\n 1\n rescue\n end").should be_false
315
- described_class.void_value_expression?("begin\n 1\n rescue\n #{keyword}\n end").should be_true
316
- described_class.void_value_expression?("begin\n 1\n rescue\n #{keyword}\n 1\n end").should be_false
317
-
318
- unless options[:no_args]
319
- described_class.void_value_expression?("begin\n #{keyword}\n rescue\n #{keyword} 1 end").should be_true
320
- described_class.void_value_expression?("begin\n 1\n #{keyword} 1\n rescue RuntimeError => e\n end").should be_true
321
- described_class.void_value_expression?("begin\n 1\n #{keyword} 1\n rescue RuntimeError\n end").should be_true
322
- described_class.void_value_expression?("begin\n 1\n #{keyword} :abc\n rescue\n end").should be_true
323
- described_class.void_value_expression?("begin\n 1\n rescue\n #{keyword} 'abc'\n end").should be_true
324
- described_class.void_value_expression?("begin\n 1\n rescue\n #{keyword} :abc\n 1\n end").should be_false
325
- end
326
-
327
- # with ensure
328
- described_class.void_value_expression?("begin\n #{keyword}\n ensure\n #{keyword} end").should be_true
329
- described_class.void_value_expression?("begin\n 1\n #{keyword}\n ensure\n end").should be_true
330
- described_class.void_value_expression?("begin\n 1\n ensure\n end").should be_false
331
- described_class.void_value_expression?("begin\n 1\n ensure\n #{keyword}\n end").should be_true
332
- described_class.void_value_expression?("begin\n 1\n ensure\n #{keyword}\n 1\n end").should be_false
333
-
334
- unless options[:no_args]
335
- described_class.void_value_expression?("begin\n #{keyword}\n ensure\n #{keyword} 1 end").should be_true
336
- described_class.void_value_expression?("begin\n 1\n #{keyword} 1\n ensure\n end").should be_true
337
- described_class.void_value_expression?("begin\n 1\n #{keyword} :abc\n ensure\n end").should be_true
338
- described_class.void_value_expression?("begin\n 1\n ensure\n #{keyword} 'abc'\n end").should be_true
339
- described_class.void_value_expression?("begin\n 1\n ensure\n #{keyword} :abc\n 1\n end").should be_false
340
- end
341
-
342
- # with ensure and rescue
343
- described_class.void_value_expression?("begin\n 1\n rescue\n 2\n ensure\n 3\n end").should be_false
344
- described_class.void_value_expression?("begin\n #{keyword}\n rescue\n 2\n ensure\n 3\n end").should be_true
345
- described_class.void_value_expression?("begin\n 1\n rescue\n #{keyword}\n ensure\n 3\n end").should be_true
346
- described_class.void_value_expression?("begin\n 1\n rescue\n 2\n ensure\n #{keyword}\n end").should be_true
347
- end
348
- end
349
-
350
- it_should_behave_like 'single line void_value_expression?', 'return'
351
- it_should_behave_like 'single line void_value_expression?', 'next'
352
- it_should_behave_like 'single line void_value_expression?', 'break'
353
-
354
- it_should_behave_like 'single line void_value_expression?', 'redo', no_args: true
355
- it_should_behave_like 'single line void_value_expression?', 'retry', no_args: true
356
-
357
52
  it 'knows when a line opens the data segment' do
358
53
  described_class.begins_data_segment?('__END__').should be_true
359
54
  described_class.begins_data_segment?('__ENDS__').should be_false
360
55
  end
361
-
362
- it 'knows when the next line modifies the current line' do
363
- described_class.next_line_modifies_current?('.meth').should be_true
364
- described_class.next_line_modifies_current?(' .meth').should be_true
365
-
366
- described_class.next_line_modifies_current?('meth').should be_false
367
- described_class.next_line_modifies_current?(' meth').should be_false
368
- end
369
56
  end