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.
- data/Readme.md +24 -3
- data/features/errors.feature +2 -2
- data/features/examples.feature +9 -9
- data/features/flags.feature +12 -10
- data/features/regression.feature +17 -3
- data/lib/seeing_is_believing.rb +23 -106
- data/lib/seeing_is_believing/binary/add_annotations.rb +3 -3
- data/lib/seeing_is_believing/program_rewriter.rb +280 -0
- data/lib/seeing_is_believing/remove_inline_comments.rb +1 -1
- data/lib/seeing_is_believing/result.rb +15 -5
- data/lib/seeing_is_believing/syntax_analyzer.rb +0 -155
- data/lib/seeing_is_believing/version.rb +1 -1
- data/seeing_is_believing.gemspec +1 -1
- data/spec/program_rewriter_spec.rb +687 -0
- data/spec/seeing_is_believing_spec.rb +66 -114
- data/spec/syntax_analyzer_spec.rb +3 -316
- metadata +10 -10
- data/lib/seeing_is_believing/expression_list.rb +0 -101
- data/spec/expression_list_spec.rb +0 -277
@@ -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 = "
|
18
|
-
invoke(input)[1].should == ["
|
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
|
-
|
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
|
-
|
102
|
-
|
103
|
-
|
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 "
|
107
|
-
values_for("<<A\n1\nA").should
|
108
|
-
values_for("
|
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'], [
|
120
|
+
__LINE__').should == [['1'], ['2'], [], [], ['5'], [], ['5'], [], [], ['10']]
|
175
121
|
end
|
176
122
|
|
177
|
-
it '
|
178
|
-
values_for("def meth \n return 1 \n end \n meth").should == [[], [], [
|
179
|
-
values_for("
|
180
|
-
values_for("
|
181
|
-
|
182
|
-
|
183
|
-
|
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
|
-
|
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'], [
|
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
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
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
|
-
|
214
|
-
(
|
215
|
-
n
|
216
|
-
|
217
|
-
|
218
|
-
|
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
|
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'
|
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
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
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 '
|
312
|
+
it 'prints the result', t:true do
|
363
313
|
call
|
364
|
-
debugger.to_s.should include "
|
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
|