seeing_is_believing 0.0.23 → 0.0.24
Sign up to get free protection for your applications and to get access to all the features.
- data/Readme.md +7 -1
- data/features/examples.feature +2 -2
- data/features/flags.feature +41 -1
- data/features/regression.feature +26 -2
- data/features/support/env.rb +4 -74
- data/lib/seeing_is_believing.rb +2 -0
- data/lib/seeing_is_believing/binary.rb +12 -3
- data/lib/seeing_is_believing/binary/arg_parser.rb +19 -16
- data/lib/seeing_is_believing/evaluate_by_moving_files.rb +6 -6
- data/lib/seeing_is_believing/result.rb +3 -1
- data/lib/seeing_is_believing/syntax_analyzer.rb +17 -4
- data/lib/seeing_is_believing/the_matrix.rb +5 -0
- data/lib/seeing_is_believing/version.rb +1 -1
- data/seeing_is_believing.gemspec +3 -0
- data/spec/arg_parser_spec.rb +24 -2
- data/spec/seeing_is_believing_spec.rb +6 -0
- data/spec/syntax_analyzer_spec.rb +158 -20
- metadata +34 -4
- data/features/step_definitions/steps.rb +0 -12
data/Readme.md
CHANGED
@@ -92,6 +92,12 @@ See [sublime-text-2-seeing-is-believing](https://github.com/JoshCheek/sublime-te
|
|
92
92
|
TextMate Integration
|
93
93
|
====================
|
94
94
|
|
95
|
+
Note: This assumes you've already set up Ruby to work with TextMate.
|
96
|
+
If not, you'll need to start there. [Here](https://rvm.io/integration/textmate/)
|
97
|
+
are instructions for RVM (I recommend the wrapper approach).
|
98
|
+
[Here](http://uberfork.com/post/12280974742/integrate-rbenv-with-textmate)
|
99
|
+
are instructions for rbenv.
|
100
|
+
|
95
101
|
Go to the bundle editor, create this new command in the Ruby bundle:
|
96
102
|
|
97
103
|
```shell
|
@@ -140,8 +146,8 @@ Known Issues
|
|
140
146
|
Todo
|
141
147
|
====
|
142
148
|
|
149
|
+
* Move as much of the SyntaxAnalyzer as possible over to Parser and ditch Ripper altogether
|
143
150
|
* Refactor ExpressionList/SeeingIsBelieving to store lines in an array instead of as a string, so everyone doesn't magically need to know when to chomp
|
144
|
-
* Make friends who actually know how to parse Ruby syntax (omg, teach me Ripper, pls, it will make this lib so much better, you have no idea O.o)
|
145
151
|
|
146
152
|
License
|
147
153
|
=======
|
data/features/examples.feature
CHANGED
@@ -235,7 +235,7 @@ Feature: Running the binary successfully
|
|
235
235
|
"""
|
236
236
|
|
237
237
|
Scenario: Reading from stdin
|
238
|
-
Given
|
238
|
+
Given the stdin content "hi!"
|
239
239
|
And the file "reads_from_stdin.rb":
|
240
240
|
"""
|
241
241
|
puts "You said: #{gets}"
|
@@ -251,7 +251,7 @@ Feature: Running the binary successfully
|
|
251
251
|
"""
|
252
252
|
|
253
253
|
Scenario: Passing the file on stdin
|
254
|
-
Given
|
254
|
+
Given the stdin content "1 + 1"
|
255
255
|
When I run "seeing_is_believing"
|
256
256
|
Then stderr is empty
|
257
257
|
And the exit status is 0
|
data/features/flags.feature
CHANGED
@@ -223,7 +223,7 @@ Feature: Using flags
|
|
223
223
|
|
224
224
|
Scenario: --as and stdin
|
225
225
|
Given the file "example.rb" "1+1"
|
226
|
-
Given
|
226
|
+
Given the stdin content:
|
227
227
|
"""
|
228
228
|
1+1
|
229
229
|
__FILE__
|
@@ -397,3 +397,43 @@ Feature: Using flags
|
|
397
397
|
1 + 1 # => 2
|
398
398
|
1 + 1 + 1 # => 3
|
399
399
|
"""
|
400
|
+
|
401
|
+
Scenario: --inherit-exit-status
|
402
|
+
Given the file "exit_status.rb" "exit 123"
|
403
|
+
When I run "seeing_is_believing exit_status.rb"
|
404
|
+
Then the exit status is 1
|
405
|
+
When I run "seeing_is_believing --inherit-exit-status exit_status.rb"
|
406
|
+
Then the exit status is 123
|
407
|
+
|
408
|
+
# Show that Ruby exceptions exit with 1, and --inherit-exit-status does as well
|
409
|
+
Scenario: --inherit-exit-status
|
410
|
+
Given the file "exception_exit_status.rb" "raise Exception"
|
411
|
+
When I run "ruby exception_exit_status.rb"
|
412
|
+
Then the exit status is 1
|
413
|
+
When I run "seeing_is_believing --inherit-exit-status exception_exit_status.rb"
|
414
|
+
Then the exit status is 1
|
415
|
+
|
416
|
+
Scenario: --inherit-exit-status in an at_exit block
|
417
|
+
Given the file "exit_status_in_at_exit_block.rb" "at_exit { exit 10 }"
|
418
|
+
When I run "seeing_is_believing exit_status_in_at_exit_block.rb"
|
419
|
+
Then the exit status is 0
|
420
|
+
When I run "seeing_is_believing --inherit-exit-status exit_status_in_at_exit_block.rb"
|
421
|
+
Then the exit status is 10
|
422
|
+
|
423
|
+
@wip
|
424
|
+
Scenario: --xmpfilter-style
|
425
|
+
Given the file "magic_comments.rb":
|
426
|
+
"""
|
427
|
+
1# =>
|
428
|
+
1 # =>
|
429
|
+
1
|
430
|
+
"""
|
431
|
+
When I run "seeing_is_believing --xmpfilter-style magic_comments.rb"
|
432
|
+
Then stderr is empty
|
433
|
+
And the exit status is 0
|
434
|
+
And stdout is:
|
435
|
+
"""
|
436
|
+
1# => 1
|
437
|
+
1 # => 1
|
438
|
+
1
|
439
|
+
"""
|
data/features/regression.feature
CHANGED
@@ -4,7 +4,7 @@ Feature:
|
|
4
4
|
I want to have tests on those bugs that I found and could not have predicted
|
5
5
|
|
6
6
|
Scenario: A program containing a single comment
|
7
|
-
Given
|
7
|
+
Given the stdin content "# single comment"
|
8
8
|
When I run "seeing_is_believing"
|
9
9
|
Then stderr is empty
|
10
10
|
And the exit status is 0
|
@@ -23,7 +23,7 @@ Feature:
|
|
23
23
|
a # ~> NameError: undefined local variable or method `a' for main:Object
|
24
24
|
"""
|
25
25
|
|
26
|
-
Scenario:
|
26
|
+
Scenario: Errors being raised in the evaluated code that don't exist in the evaluating code
|
27
27
|
Given the file "raising_custom_errors.rb":
|
28
28
|
"""
|
29
29
|
MyError = Class.new StandardError
|
@@ -36,3 +36,27 @@ Feature:
|
|
36
36
|
When I run "seeing_is_believing raising_custom_errors.rb"
|
37
37
|
Then stderr is empty
|
38
38
|
And the exit status is 1
|
39
|
+
|
40
|
+
Scenario: statements that inherit void value expressions
|
41
|
+
Given the file "statements_that_inherit_void_value_expressions.rb":
|
42
|
+
"""
|
43
|
+
def m
|
44
|
+
if true
|
45
|
+
return 1
|
46
|
+
end
|
47
|
+
end
|
48
|
+
m
|
49
|
+
"""
|
50
|
+
When I run "seeing_is_believing statements_that_inherit_void_value_expressions.rb"
|
51
|
+
Then stderr is empty
|
52
|
+
And the exit status is 0
|
53
|
+
Then stdout is:
|
54
|
+
"""
|
55
|
+
def m
|
56
|
+
if true
|
57
|
+
return 1
|
58
|
+
end
|
59
|
+
end # => nil
|
60
|
+
m # => 1
|
61
|
+
"""
|
62
|
+
|
data/features/support/env.rb
CHANGED
@@ -1,78 +1,8 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
require 'open3'
|
3
1
|
require_relative '../../lib/seeing_is_believing/version'
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
status.exitstatus
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
extend self
|
14
|
-
|
15
|
-
def write_file(filename, body)
|
16
|
-
in_proving_grounds do
|
17
|
-
FileUtils.mkdir_p File.dirname filename
|
18
|
-
File.open(filename, 'w') { |file| file.write body }
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def execute(command, stdin_data=nil)
|
23
|
-
stdin_data ||= ''
|
24
|
-
in_proving_grounds do
|
25
|
-
with_bin_in_path do
|
26
|
-
Invocation.new *Open3.capture3(command, stdin_data: stdin_data)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def in_proving_grounds(&block)
|
32
|
-
Dir.chdir proving_grounds_dir, &block
|
33
|
-
end
|
34
|
-
|
35
|
-
def proving_grounds_dir
|
36
|
-
File.join root_dir, 'proving_grounds'
|
37
|
-
end
|
38
|
-
|
39
|
-
def root_dir
|
40
|
-
@root_dir ||= begin
|
41
|
-
dir = File.expand_path Dir.pwd
|
42
|
-
dir = File.dirname dir until Dir["#{dir}/*"].map { |fn| File.basename fn }.include?('lib')
|
43
|
-
dir
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def make_proving_grounds
|
48
|
-
FileUtils.mkdir_p proving_grounds_dir
|
49
|
-
end
|
50
|
-
|
51
|
-
def bin_dir
|
52
|
-
File.join root_dir, "bin"
|
53
|
-
end
|
54
|
-
|
55
|
-
def path_to(filename)
|
56
|
-
in_proving_grounds { File.join proving_grounds_dir, filename }
|
57
|
-
end
|
58
|
-
|
59
|
-
# workaround for Ruby 2.0 bug where passing the new path as the first arg wasn't working
|
60
|
-
# bug report submitted here: http://bugs.ruby-lang.org/issues/8004
|
61
|
-
def with_bin_in_path
|
62
|
-
original_path = ENV['PATH']
|
63
|
-
ENV['PATH'] = "#{bin_dir}:#{ENV['PATH']}"
|
64
|
-
yield
|
65
|
-
ensure
|
66
|
-
ENV['PATH'] = original_path
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
CommandLineHelpers.make_proving_grounds
|
71
|
-
|
72
|
-
module GeneralHelpers
|
73
|
-
def eval_curlies(string)
|
74
|
-
string.gsub(/{{(.*?)}}/) { eval $1 }
|
75
|
-
end
|
3
|
+
require 'haiti'
|
4
|
+
Haiti.configure do |config|
|
5
|
+
config.proving_grounds_dir = File.expand_path '../../../proving_grounds', __FILE__
|
6
|
+
config.bin_dir = File.expand_path '../../../bin', __FILE__
|
76
7
|
end
|
77
8
|
|
78
|
-
World GeneralHelpers
|
data/lib/seeing_is_believing.rb
CHANGED
@@ -108,6 +108,8 @@ class SeeingIsBelieving
|
|
108
108
|
"rescue Exception;"\
|
109
109
|
"line_number = $!.backtrace.grep(/\#{__FILE__}/).first[/:\\d+/][1..-1].to_i;"\
|
110
110
|
"$seeing_is_believing_current_result.record_exception line_number, $!;"\
|
111
|
+
"$seeing_is_believing_current_result.exitstatus = 1;"\
|
112
|
+
"$seeing_is_believing_current_result.exitstatus = $!.status if $!.kind_of? SystemExit;"\
|
111
113
|
"end"
|
112
114
|
end
|
113
115
|
|
@@ -28,16 +28,25 @@ class SeeingIsBelieving
|
|
28
28
|
elsif invalid_syntax? then print_syntax_error ; NONDISPLAYABLE_ERROR_STATUS
|
29
29
|
elsif program_timedout? then print_timeout_error ; NONDISPLAYABLE_ERROR_STATUS
|
30
30
|
elsif something_blew_up? then print_unexpected_error ; NONDISPLAYABLE_ERROR_STATUS
|
31
|
-
else print_program ;
|
32
|
-
DISPLAYABLE_ERROR_STATUS :
|
33
|
-
SUCCESS_STATUS)
|
31
|
+
else print_program ; program_exit_status
|
34
32
|
end
|
35
33
|
end
|
36
34
|
|
35
|
+
# uhm, this is dumb
|
37
36
|
alias exitstatus call
|
38
37
|
|
39
38
|
private
|
40
39
|
|
40
|
+
def program_exit_status
|
41
|
+
if flags[:inherit_exit_status]
|
42
|
+
results.exitstatus
|
43
|
+
elsif results.has_exception?
|
44
|
+
DISPLAYABLE_ERROR_STATUS
|
45
|
+
else
|
46
|
+
SUCCESS_STATUS
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
41
50
|
def has_filename?
|
42
51
|
flags[:filename]
|
43
52
|
end
|
@@ -21,22 +21,24 @@ class SeeingIsBelieving
|
|
21
21
|
@result ||= begin
|
22
22
|
until args.empty?
|
23
23
|
case (arg = args.shift)
|
24
|
-
when '-h', '--help'
|
25
|
-
when '-v', '--version'
|
26
|
-
when '-c', '--clean'
|
27
|
-
when '-
|
28
|
-
when '-
|
29
|
-
when '-
|
30
|
-
when '-
|
31
|
-
when '-
|
32
|
-
when '-
|
33
|
-
when '-
|
34
|
-
when '-
|
35
|
-
when '-
|
36
|
-
when '-
|
37
|
-
when
|
38
|
-
when '-
|
39
|
-
when
|
24
|
+
when '-h', '--help' then options[:help] = self.class.help_screen
|
25
|
+
when '-v', '--version' then options[:version] = true
|
26
|
+
when '-c', '--clean' then options[:clean] = true
|
27
|
+
when '-x', '--xmpfilter-style' then options[:xmpfilter_style] = true
|
28
|
+
when '-i', '--inherit-exit-status' then options[:inherit_exit_status] = true
|
29
|
+
when '-l', '--start-line' then extract_positive_int_for :start_line, arg
|
30
|
+
when '-L', '--end-line' then extract_positive_int_for :end_line, arg
|
31
|
+
when '-d', '--line-length' then extract_positive_int_for :line_length, arg
|
32
|
+
when '-D', '--result-length' then extract_positive_int_for :result_length, arg
|
33
|
+
when '-t', '--timeout' then extract_non_negative_float_for :timeout, arg
|
34
|
+
when '-r', '--require' then next_arg("#{arg} expected a filename as the following argument but did not see one") { |filename| options[:require] << filename }
|
35
|
+
when '-I', '--load-path' then next_arg("#{arg} expected a directory as the following argument but did not see one") { |dir| options[:load_path] << dir }
|
36
|
+
when '-e', '--program' then next_arg("#{arg} expected a program as the following argument but did not see one") { |program| options[:program] = program }
|
37
|
+
when '-a', '--as' then next_arg("#{arg} expected a filename as the following argument but did not see one") { |filename| options[:as] = filename }
|
38
|
+
when '-s', '--alignment-strategy' then extract_alignment_strategy
|
39
|
+
when /\A-K(.+)/ then options[:encoding] = $1
|
40
|
+
when '-K', '--encoding' then next_arg("#{arg} expects an encoding, see `man ruby` for possibile values") { |encoding| options[:encoding] = encoding }
|
41
|
+
when /^-/ then options[:errors] << "Unknown option: #{arg.inspect}" # unknown flags
|
40
42
|
else
|
41
43
|
filenames << arg
|
42
44
|
options[:filename] = arg
|
@@ -145,6 +147,7 @@ Usage: seeing_is_believing [options] [filename]
|
|
145
147
|
-K, --encoding encoding # sets file encoding, equivalent to Ruby's -Kx (see `man ruby` for valid values)
|
146
148
|
-a, --as filename # run the program as if it was the specified filename
|
147
149
|
-c, --clean # remove annotations from previous runs of seeing_is_believing
|
150
|
+
-i, --inherit-exit-status # exit with the exit status of the program being eval
|
148
151
|
-v, --version # print the version (#{VERSION})
|
149
152
|
-h, --help # this help screen
|
150
153
|
HELP_SCREEN
|
@@ -13,6 +13,7 @@
|
|
13
13
|
|
14
14
|
require 'yaml'
|
15
15
|
require 'open3'
|
16
|
+
require 'timeout'
|
16
17
|
require 'stringio'
|
17
18
|
require 'fileutils'
|
18
19
|
require 'seeing_is_believing/error'
|
@@ -43,8 +44,7 @@ class SeeingIsBelieving
|
|
43
44
|
write_program_to_file
|
44
45
|
begin
|
45
46
|
evaluate_file
|
46
|
-
fail
|
47
|
-
deserialize_result
|
47
|
+
deserialize_result.tap { |result| fail if result.bug_in_sib? }
|
48
48
|
# Okay, really, I should wrap this in another exception and raise it on up,
|
49
49
|
# but for now, I'm feeling a little lazy and am not going to do it
|
50
50
|
rescue Exception
|
@@ -57,10 +57,6 @@ class SeeingIsBelieving
|
|
57
57
|
}
|
58
58
|
end
|
59
59
|
|
60
|
-
def error_implies_bug_in_sib?(error)
|
61
|
-
not error.kind_of? Timeout::Error
|
62
|
-
end
|
63
|
-
|
64
60
|
def file_directory
|
65
61
|
File.dirname filename
|
66
62
|
end
|
@@ -73,6 +69,10 @@ class SeeingIsBelieving
|
|
73
69
|
|
74
70
|
attr_accessor :stdout, :stderr, :exitstatus
|
75
71
|
|
72
|
+
def error_implies_bug_in_sib?(error)
|
73
|
+
not error.kind_of? Timeout::Error
|
74
|
+
end
|
75
|
+
|
76
76
|
def we_will_not_overwrite_existing_tempfile!
|
77
77
|
raise TempFileAlreadyExists.new(filename, temp_filename) if File.exist? temp_filename
|
78
78
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'ripper'
|
2
|
+
require 'parser/current'
|
2
3
|
|
3
4
|
class SeeingIsBelieving
|
4
5
|
class SyntaxAnalyzer < Ripper::SexpBuilder
|
@@ -156,10 +157,22 @@ class SeeingIsBelieving
|
|
156
157
|
|
157
158
|
# RETURNS
|
158
159
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
160
|
+
def self.void_value_expression?(code_or_ast)
|
161
|
+
ast = code_or_ast
|
162
|
+
ast = Parser::CurrentRuby.parse(code_or_ast) if code_or_ast.kind_of? String
|
163
|
+
|
164
|
+
case ast && ast.type
|
165
|
+
when :begin, :resbody
|
166
|
+
void_value_expression?(ast.children[-1])
|
167
|
+
when :rescue, :ensure
|
168
|
+
ast.children.any? { |child| void_value_expression? child }
|
169
|
+
when :if
|
170
|
+
void_value_expression?(ast.children[1]) || void_value_expression?(ast.children[2])
|
171
|
+
when :return, :next, :redo, :retry, :break
|
172
|
+
true
|
173
|
+
else
|
174
|
+
false
|
175
|
+
end
|
163
176
|
end
|
164
177
|
|
165
178
|
# HERE DOCS
|
@@ -15,5 +15,10 @@ at_exit do
|
|
15
15
|
$seeing_is_believing_current_result.stdout = fake_stdout.string
|
16
16
|
$seeing_is_believing_current_result.stderr = fake_stderr.string
|
17
17
|
|
18
|
+
$seeing_is_believing_current_result.exitstatus ||= 0
|
19
|
+
$seeing_is_believing_current_result.exitstatus = 1 if $!
|
20
|
+
$seeing_is_believing_current_result.exitstatus = $!.status if $!.kind_of? SystemExit
|
21
|
+
$seeing_is_believing_current_result.bug_in_sib = $! && ! $!.kind_of?(SystemExit)
|
22
|
+
|
18
23
|
real_stdout.write YAML.dump $seeing_is_believing_current_result
|
19
24
|
end
|
data/seeing_is_believing.gemspec
CHANGED
@@ -19,6 +19,9 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
|
+
s.add_dependency "parser", "~> 1.4"
|
23
|
+
|
24
|
+
s.add_development_dependency "haiti", "~> 0.0.3"
|
22
25
|
s.add_development_dependency "rake", "~> 10.0.3"
|
23
26
|
s.add_development_dependency "rspec", "~> 2.12.0"
|
24
27
|
s.add_development_dependency "cucumber", "~> 1.2.1"
|
data/spec/arg_parser_spec.rb
CHANGED
@@ -57,8 +57,8 @@ describe SeeingIsBelieving::Binary::ArgParser do
|
|
57
57
|
|
58
58
|
specify 'unknown options set an error' do
|
59
59
|
parse(['--xyz']).should have_error 'Unknown option: "--xyz"'
|
60
|
-
parse(['-
|
61
|
-
parse(['-
|
60
|
+
parse(['-y']).should have_error 'Unknown option: "-y"'
|
61
|
+
parse(['-y', 'b']).should have_error 'Unknown option: "-y"'
|
62
62
|
end
|
63
63
|
|
64
64
|
example 'example: multiple args' do
|
@@ -311,5 +311,27 @@ describe SeeingIsBelieving::Binary::ArgParser do
|
|
311
311
|
parse(['-s' ]).should have_error /alignment-strategy/
|
312
312
|
end
|
313
313
|
end
|
314
|
+
|
315
|
+
describe ':inherit_exit_status' do
|
316
|
+
it 'defaults to false' do
|
317
|
+
parse([])[:inherit_exit_status].should be_false
|
318
|
+
end
|
319
|
+
|
320
|
+
it 'can be set with --inherit-exit-status or -i' do
|
321
|
+
parse(['--inherit-exit-status'])[:inherit_exit_status].should be_true
|
322
|
+
parse(['-i'])[:inherit_exit_status].should be_true
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
describe ':xmpfilter_style' do
|
327
|
+
it 'defaults to false' do
|
328
|
+
parse([])[:xmpfilter_style].should be_false
|
329
|
+
end
|
330
|
+
|
331
|
+
it 'can be set with --xmpfilter-style or -x' do
|
332
|
+
parse(['--xmpfilter-style'])[:xmpfilter_style].should be_true
|
333
|
+
parse(['-x'])[:xmpfilter_style].should be_true
|
334
|
+
end
|
335
|
+
end
|
314
336
|
end
|
315
337
|
|
@@ -284,6 +284,12 @@ describe SeeingIsBelieving do
|
|
284
284
|
expect { invoke "sleep 0.2", timeout: 0.1 }.to raise_error Timeout::Error
|
285
285
|
end
|
286
286
|
|
287
|
+
it 'records the exit status' do
|
288
|
+
invoke('raise "omg"').exitstatus.should == 1
|
289
|
+
invoke('exit 123').exitstatus.should == 123
|
290
|
+
invoke('at_exit { exit 121 }').exitstatus.should == 121
|
291
|
+
end
|
292
|
+
|
287
293
|
it 'can record the middle of a chain of calls', not_implemented: true do
|
288
294
|
values_for("[*1..5]
|
289
295
|
.select(&:even?)
|
@@ -171,37 +171,175 @@ describe SeeingIsBelieving::SyntaxAnalyzer do
|
|
171
171
|
end
|
172
172
|
end
|
173
173
|
|
174
|
-
shared_examples_for 'void_value_expression?' do |keyword|
|
175
|
-
|
174
|
+
shared_examples_for 'single line void_value_expression?' do |keyword, options={}|
|
175
|
+
specify "`#{keyword}` returns true when the expression ends in #{keyword} without an argument" do
|
176
176
|
described_class.void_value_expression?("#{keyword}").should be_true
|
177
|
-
described_class.void_value_expression?("#{keyword}
|
178
|
-
described_class.void_value_expression?("#{keyword} 1").should be_true
|
179
|
-
described_class.void_value_expression?("#{keyword} 1\n").should be_true
|
180
|
-
described_class.void_value_expression?("#{keyword} 1 if true").should be_true
|
181
|
-
described_class.void_value_expression?("#{keyword} 1 if false").should be_true
|
177
|
+
described_class.void_value_expression?("#{keyword} if true").should be_true
|
182
178
|
described_class.void_value_expression?("o.#{keyword}").should be_false
|
183
179
|
described_class.void_value_expression?(":#{keyword}").should be_false
|
180
|
+
described_class.void_value_expression?(":'#{keyword}'").should be_false
|
184
181
|
described_class.void_value_expression?("'#{keyword}'").should be_false
|
185
|
-
described_class.void_value_expression?("def a\n#{keyword} 1\nend").should be_false
|
186
|
-
described_class.void_value_expression?("-> {\n#{keyword} 1\n}").should be_false
|
187
|
-
described_class.void_value_expression?("Proc.new {\n#{keyword} 1\n}").should be_false
|
188
|
-
described_class.void_value_expression?("#{keyword}_something").should be_false
|
189
182
|
described_class.void_value_expression?("def a\n#{keyword}\nend").should be_false
|
183
|
+
described_class.void_value_expression?("-> {\n#{keyword}\n}").should be_false
|
184
|
+
described_class.void_value_expression?("Proc.new {\n#{keyword}\n}").should be_false
|
185
|
+
described_class.void_value_expression?("#{keyword}_something").should be_false
|
186
|
+
described_class.void_value_expression?("'#{keyword}\n#{keyword}\n#{keyword}'").should be_false
|
187
|
+
|
188
|
+
unless options[:no_args]
|
189
|
+
described_class.void_value_expression?("#{keyword}(1)").should be_true
|
190
|
+
described_class.void_value_expression?("#{keyword} 1").should be_true
|
191
|
+
described_class.void_value_expression?("#{keyword} 1\n").should be_true
|
192
|
+
described_class.void_value_expression?("#{keyword} 1 if true").should be_true
|
193
|
+
described_class.void_value_expression?("#{keyword} 1 if false").should be_true
|
194
|
+
described_class.void_value_expression?("def a\n#{keyword} 1\nend").should be_false
|
195
|
+
described_class.void_value_expression?("-> {\n#{keyword} 1\n}").should be_false
|
196
|
+
described_class.void_value_expression?("Proc.new {\n#{keyword} 1\n}").should be_false
|
197
|
+
described_class.void_value_expression?("#{keyword} \\\n1").should be_true
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
it "knows when an if statement ends in `#{keyword}`" do
|
202
|
+
# if
|
203
|
+
described_class.void_value_expression?("if true\n#{keyword}\nend").should be_true
|
204
|
+
described_class.void_value_expression?("if true\n #{keyword}\nend").should be_true
|
205
|
+
described_class.void_value_expression?("if true\n 1+1\n #{keyword}\nend").should be_true
|
206
|
+
described_class.void_value_expression?("if true\n #{keyword}\n 1+1\n end").should be_false
|
207
|
+
described_class.void_value_expression?("123 && if true\n #{keyword}\nend").should be_false
|
208
|
+
described_class.void_value_expression?("def m\n if true\n #{keyword}\nend\n end").should be_false
|
209
|
+
described_class.void_value_expression?("if true; #{keyword}; end").should be_true
|
210
|
+
described_class.void_value_expression?("if true; 1; end").should be_false
|
211
|
+
|
212
|
+
# if .. elsif
|
213
|
+
described_class.void_value_expression?("if true\n #{keyword}\n elsif true\n 1\n end").should be_true
|
214
|
+
described_class.void_value_expression?("if true\n 1\n elsif true\n #{keyword}\n end").should be_true
|
215
|
+
described_class.void_value_expression?("if true\n #{keyword}\n 2\n elsif true\n 1\n end").should be_false
|
216
|
+
described_class.void_value_expression?("if true\n 1\n elsif true\n #{keyword}\n 2\n end").should be_false
|
217
|
+
|
218
|
+
# if .. else
|
219
|
+
described_class.void_value_expression?("if true\n #{keyword}\n else 1\n end").should be_true
|
220
|
+
described_class.void_value_expression?("if true\n 1\n else\n #{keyword}\n end").should be_true
|
221
|
+
described_class.void_value_expression?("if true\n #{keyword}\n 2\n else 1\n end").should be_false
|
222
|
+
described_class.void_value_expression?("if true\n 1\n else\n #{keyword}\n 2\n end").should be_false
|
223
|
+
|
224
|
+
# if .. elsif .. else .. end
|
225
|
+
described_class.void_value_expression?("if true\n #{keyword}\nelsif true\n 1 else 1\n end").should be_true
|
226
|
+
described_class.void_value_expression?("if true\n 1\n elsif true\n #{keyword}\n else\n 1\n end").should be_true
|
227
|
+
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
|
228
|
+
described_class.void_value_expression?("if true\n 1\n elsif true\n 1\n else\n #{keyword}\n end").should be_true
|
229
|
+
described_class.void_value_expression?("if true\n #{keyword}\n 2\nelsif true\n 1 else 1\n end").should be_false
|
230
|
+
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
|
231
|
+
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
|
232
|
+
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
|
233
|
+
|
234
|
+
unless options[:no_args]
|
235
|
+
# if
|
236
|
+
described_class.void_value_expression?("if true\n#{keyword} 1\nend").should be_true
|
237
|
+
described_class.void_value_expression?("if true\n #{keyword} 1\nend").should be_true
|
238
|
+
described_class.void_value_expression?("if true\n 1+1\n #{keyword} 1\nend").should be_true
|
239
|
+
described_class.void_value_expression?("if true\n #{keyword} 1\n 1+1\n end").should be_false
|
240
|
+
described_class.void_value_expression?("123 && if true\n #{keyword} 1\nend").should be_false
|
241
|
+
described_class.void_value_expression?("def m\n if true\n #{keyword} 1\nend\n end").should be_false
|
242
|
+
described_class.void_value_expression?("if true; #{keyword} 1; end").should be_true
|
243
|
+
described_class.void_value_expression?("if true; 1; end").should be_false
|
244
|
+
|
245
|
+
# if .. elsif
|
246
|
+
described_class.void_value_expression?("if true\n #{keyword} 1\n elsif true\n 1\n end").should be_true
|
247
|
+
described_class.void_value_expression?("if true\n 1\n elsif true\n #{keyword}\n end").should be_true
|
248
|
+
described_class.void_value_expression?("if true\n #{keyword} 1\n 2\n elsif true\n 1\n end").should be_false
|
249
|
+
described_class.void_value_expression?("if true\n 1\n elsif true\n #{keyword}\n 2\n end").should be_false
|
250
|
+
|
251
|
+
# if .. else
|
252
|
+
described_class.void_value_expression?("if true\n #{keyword} 1\n else 1\n end").should be_true
|
253
|
+
described_class.void_value_expression?("if true\n 1\n else\n #{keyword}\n end").should be_true
|
254
|
+
described_class.void_value_expression?("if true\n #{keyword} 1\n 2\n else 1\n end").should be_false
|
255
|
+
described_class.void_value_expression?("if true\n 1\n else\n #{keyword}\n 2\n end").should be_false
|
256
|
+
|
257
|
+
# if .. elsif .. else .. end
|
258
|
+
described_class.void_value_expression?("if true\n #{keyword} 1\nelsif true\n 1 else 1\n end").should be_true
|
259
|
+
described_class.void_value_expression?("if true\n 1\n elsif true\n #{keyword}\n else\n 1\n end").should be_true
|
260
|
+
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
|
261
|
+
described_class.void_value_expression?("if true\n 1\n elsif true\n 1\n else\n #{keyword}\n end").should be_true
|
262
|
+
described_class.void_value_expression?("if true\n #{keyword} 1\n 2\nelsif true\n 1 else 1\n end").should be_false
|
263
|
+
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
|
264
|
+
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
|
265
|
+
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
|
266
|
+
end
|
190
267
|
end
|
191
268
|
|
192
|
-
it "
|
193
|
-
|
194
|
-
|
195
|
-
|
269
|
+
it "knows when a begin statement ends in `#{keyword}`" do
|
270
|
+
described_class.void_value_expression?("begin\n #{keyword}\n end").should be_true
|
271
|
+
described_class.void_value_expression?("begin\n 1\n #{keyword}\n end").should be_true
|
272
|
+
described_class.void_value_expression?("begin\n #{keyword}\n 1\n end").should be_false
|
273
|
+
described_class.void_value_expression?("begin\n 1\n #{keyword}\n 1\n end").should be_false
|
274
|
+
|
275
|
+
unless options[:no_args]
|
276
|
+
described_class.void_value_expression?("begin\n #{keyword} '123' \n end").should be_true
|
277
|
+
described_class.void_value_expression?("begin\n 1\n #{keyword} 456\n end").should be_true
|
278
|
+
described_class.void_value_expression?("begin\n #{keyword} :'789'\n 1\n end").should be_false
|
279
|
+
described_class.void_value_expression?("begin\n 1\n #{keyword} /101112/\n 1\n end").should be_false
|
280
|
+
end
|
281
|
+
|
282
|
+
# I don't know that the rest of these hold across all versions of Ruby since they make no fucking sense
|
283
|
+
# so even though some of them can technically be non-vve,
|
284
|
+
# I'm still going to call any one of them a vve
|
285
|
+
#
|
286
|
+
# e.g. (tested on 2.0)
|
287
|
+
# this is allowed
|
288
|
+
# -> { a = begin; return
|
289
|
+
# rescue; return
|
290
|
+
# ensure; return
|
291
|
+
# end }
|
292
|
+
# this is not
|
293
|
+
# -> { a = begin; return
|
294
|
+
# end }
|
295
|
+
|
296
|
+
# with rescue...
|
297
|
+
described_class.void_value_expression?("begin\n #{keyword}\n rescue\n #{keyword} end").should be_true
|
298
|
+
described_class.void_value_expression?("begin\n 1\n #{keyword}\n rescue RuntimeError => e\n end").should be_true
|
299
|
+
described_class.void_value_expression?("begin\n 1\n #{keyword}\n rescue RuntimeError\n end").should be_true
|
300
|
+
described_class.void_value_expression?("begin\n 1\n #{keyword}\n rescue\n end").should be_true
|
301
|
+
described_class.void_value_expression?("begin\n 1\n rescue\n end").should be_false
|
302
|
+
described_class.void_value_expression?("begin\n 1\n rescue\n #{keyword}\n end").should be_true
|
303
|
+
described_class.void_value_expression?("begin\n 1\n rescue\n #{keyword}\n 1\n end").should be_false
|
304
|
+
|
305
|
+
unless options[:no_args]
|
306
|
+
described_class.void_value_expression?("begin\n #{keyword}\n rescue\n #{keyword} 1 end").should be_true
|
307
|
+
described_class.void_value_expression?("begin\n 1\n #{keyword} 1\n rescue RuntimeError => e\n end").should be_true
|
308
|
+
described_class.void_value_expression?("begin\n 1\n #{keyword} 1\n rescue RuntimeError\n end").should be_true
|
309
|
+
described_class.void_value_expression?("begin\n 1\n #{keyword} :abc\n rescue\n end").should be_true
|
310
|
+
described_class.void_value_expression?("begin\n 1\n rescue\n #{keyword} 'abc'\n end").should be_true
|
311
|
+
described_class.void_value_expression?("begin\n 1\n rescue\n #{keyword} :abc\n 1\n end").should be_false
|
312
|
+
end
|
313
|
+
|
314
|
+
# with ensure
|
315
|
+
described_class.void_value_expression?("begin\n #{keyword}\n ensure\n #{keyword} end").should be_true
|
316
|
+
described_class.void_value_expression?("begin\n 1\n #{keyword}\n ensure\n end").should be_true
|
317
|
+
described_class.void_value_expression?("begin\n 1\n ensure\n end").should be_false
|
318
|
+
described_class.void_value_expression?("begin\n 1\n ensure\n #{keyword}\n end").should be_true
|
319
|
+
described_class.void_value_expression?("begin\n 1\n ensure\n #{keyword}\n 1\n end").should be_false
|
320
|
+
|
321
|
+
unless options[:no_args]
|
322
|
+
described_class.void_value_expression?("begin\n #{keyword}\n ensure\n #{keyword} 1 end").should be_true
|
323
|
+
described_class.void_value_expression?("begin\n 1\n #{keyword} 1\n ensure\n end").should be_true
|
324
|
+
described_class.void_value_expression?("begin\n 1\n #{keyword} :abc\n ensure\n end").should be_true
|
325
|
+
described_class.void_value_expression?("begin\n 1\n ensure\n #{keyword} 'abc'\n end").should be_true
|
326
|
+
described_class.void_value_expression?("begin\n 1\n ensure\n #{keyword} :abc\n 1\n end").should be_false
|
196
327
|
end
|
328
|
+
|
329
|
+
# with ensure and rescue
|
330
|
+
described_class.void_value_expression?("begin\n 1\n rescue\n 2\n ensure\n 3\n end").should be_false
|
331
|
+
described_class.void_value_expression?("begin\n #{keyword}\n rescue\n 2\n ensure\n 3\n end").should be_true
|
332
|
+
described_class.void_value_expression?("begin\n 1\n rescue\n #{keyword}\n ensure\n 3\n end").should be_true
|
333
|
+
described_class.void_value_expression?("begin\n 1\n rescue\n 2\n ensure\n #{keyword}\n end").should be_true
|
197
334
|
end
|
198
335
|
end
|
199
336
|
|
200
|
-
it_should_behave_like 'void_value_expression?', 'return'
|
201
|
-
it_should_behave_like 'void_value_expression?', 'next'
|
202
|
-
it_should_behave_like 'void_value_expression?', '
|
203
|
-
|
204
|
-
it_should_behave_like 'void_value_expression?', '
|
337
|
+
it_should_behave_like 'single line void_value_expression?', 'return'
|
338
|
+
it_should_behave_like 'single line void_value_expression?', 'next'
|
339
|
+
it_should_behave_like 'single line void_value_expression?', 'break'
|
340
|
+
|
341
|
+
it_should_behave_like 'single line void_value_expression?', 'redo', no_args: true
|
342
|
+
it_should_behave_like 'single line void_value_expression?', 'retry', no_args: true
|
205
343
|
|
206
344
|
it 'knows when a line opens the data segment' do
|
207
345
|
described_class.begins_data_segment?('__END__').should be_true
|
metadata
CHANGED
@@ -2,15 +2,47 @@
|
|
2
2
|
name: seeing_is_believing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.24
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Josh Cheek
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-06-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
version_requirements: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.4'
|
20
|
+
none: false
|
21
|
+
name: parser
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
requirement: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '1.4'
|
29
|
+
none: false
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
version_requirements: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ~>
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 0.0.3
|
36
|
+
none: false
|
37
|
+
name: haiti
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
requirement: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 0.0.3
|
45
|
+
none: false
|
14
46
|
- !ruby/object:Gem::Dependency
|
15
47
|
version_requirements: !ruby/object:Gem::Requirement
|
16
48
|
requirements:
|
@@ -95,7 +127,6 @@ files:
|
|
95
127
|
- features/examples.feature
|
96
128
|
- features/flags.feature
|
97
129
|
- features/regression.feature
|
98
|
-
- features/step_definitions/steps.rb
|
99
130
|
- features/support/env.rb
|
100
131
|
- lib/seeing_is_believing.rb
|
101
132
|
- lib/seeing_is_believing/binary.rb
|
@@ -158,7 +189,6 @@ test_files:
|
|
158
189
|
- features/examples.feature
|
159
190
|
- features/flags.feature
|
160
191
|
- features/regression.feature
|
161
|
-
- features/step_definitions/steps.rb
|
162
192
|
- features/support/env.rb
|
163
193
|
- spec/arg_parser_spec.rb
|
164
194
|
- spec/evaluate_by_moving_files_spec.rb
|
@@ -1,12 +0,0 @@
|
|
1
|
-
Given('the file "$filename" "$body"') { |filename, body| CommandLineHelpers.write_file filename, eval_curlies(body) }
|
2
|
-
Given('the file "$filename":') { |filename, body| CommandLineHelpers.write_file filename, eval_curlies(body) }
|
3
|
-
Given('I have the stdin content "$content"') { |content| @stdin_data = eval_curlies(content) }
|
4
|
-
Given('I have the stdin content:') { |content| @stdin_data = eval_curlies(content) }
|
5
|
-
When('I run "$command"') { |command| @last_executed = CommandLineHelpers.execute command, @stdin_data }
|
6
|
-
When("I run '$command'") { |command| @last_executed = CommandLineHelpers.execute command, @stdin_data }
|
7
|
-
Then(/^(stderr|stdout) is:$/) { |stream_name, output| @last_executed.send(stream_name).chomp.should == eval_curlies(output) }
|
8
|
-
Then(/^(stderr|stdout) is ["'](.*?)["']$/) { |stream_name, output| @last_executed.send(stream_name).chomp.should == eval_curlies(output) }
|
9
|
-
Then(/^(stderr|stdout) is empty$/) { |stream_name| @last_executed.send(stream_name).should == '' }
|
10
|
-
Then(/^(stderr|stdout) is not empty$/) { |stream_name| @last_executed.send(stream_name).chomp.should_not be_empty }
|
11
|
-
Then(/^(stderr|stdout) includes "([^"]*)"$/) { |stream_name, content| @last_executed.send(stream_name).should include eval_curlies(content) }
|
12
|
-
Then('the exit status is $status') { |status| @last_executed.exitstatus.to_s.should == status }
|