seeing_is_believing 1.0.1 → 2.0.0.beta1

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.
@@ -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