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