seeing_is_believing 0.0.23 → 0.0.24
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 +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 }
|