seeing_is_believing 2.0.0.beta2 → 2.0.0.beta3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Readme.md +53 -18
- data/features/flags.feature +18 -0
- data/lib/seeing_is_believing/binary/add_annotations.rb +10 -12
- data/lib/seeing_is_believing/binary/clean_body.rb +2 -6
- data/lib/seeing_is_believing/binary/commentable_lines.rb +9 -43
- data/lib/seeing_is_believing/binary/{arg_parser.rb → parse_args.rb} +102 -14
- data/lib/seeing_is_believing/binary/rewrite_comments.rb +2 -6
- data/lib/seeing_is_believing/binary.rb +8 -4
- data/lib/seeing_is_believing/debugger.rb +12 -17
- data/lib/seeing_is_believing/error.rb +14 -0
- data/lib/seeing_is_believing/evaluate_by_moving_files.rb +16 -17
- data/lib/seeing_is_believing/parser_helpers.rb +51 -0
- data/lib/seeing_is_believing/version.rb +1 -1
- data/lib/seeing_is_believing/wrap_expressions.rb +12 -49
- data/lib/seeing_is_believing.rb +5 -2
- data/seeing_is_believing.gemspec +1 -1
- data/spec/binary/arg_parser_spec.rb +26 -7
- data/spec/debugger_spec.rb +29 -16
- data/spec/evaluate_by_moving_files_spec.rb +7 -7
- data/spec/seeing_is_believing_spec.rb +31 -7
- data/spec/wrap_expressions_spec.rb +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a95d8680853f82d8aee58a8ba40d16a113662f20
|
4
|
+
data.tar.gz: 6e9fecb99be2adf05d75bb42d2c8a37de1ff1c7b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 291941c2ca6975b233ecfe9f8428f40638331839ec29591d955333d49a3bf975ed0478ca67059e41a7583ddd8b18e9140a9f632b8242665d8fdfed939e8bf319
|
7
|
+
data.tar.gz: 138ae24e20da808a5ea5eb31bcc9ab4eede0163054a130478f79f1e00842b5c56b073f104c98c952f77e0b5698ca6e626691e4818137db136811eaa4e64fff30
|
data/Readme.md
CHANGED
@@ -98,26 +98,59 @@ are instructions for RVM (I recommend the wrapper approach).
|
|
98
98
|
[Here](http://uberfork.com/post/12280974742/integrate-rbenv-with-textmate)
|
99
99
|
are instructions for rbenv.
|
100
100
|
|
101
|
-
Go to the bundle editor, create
|
101
|
+
Go to the bundle editor, create a new command (I put it in the Ruby bundle)
|
102
|
+
You can name it what you want, I went with "seeing is believing annotate all lines"
|
102
103
|
|
103
104
|
```shell
|
105
|
+
#!/bin/bash
|
106
|
+
|
107
|
+
# set result length because TextMate has difficulty displaying long lines
|
108
|
+
default_options=""
|
109
|
+
default_options="$default_options -Ku"
|
110
|
+
default_options="$default_options --result-length 200"
|
111
|
+
default_options="$default_options --alignment-strategy chunk"
|
112
|
+
default_options="$default_options --timeout 12"
|
113
|
+
|
104
114
|
if [ -z "$TM_FILEPATH" ]; then
|
105
|
-
"${TM_RUBY}" -S seeing_is_believing
|
115
|
+
"${TM_RUBY}" -S seeing_is_believing $default_options
|
106
116
|
else
|
107
|
-
"${TM_RUBY}" -S seeing_is_believing
|
117
|
+
"${TM_RUBY}" -S seeing_is_believing $default_options --as "$TM_FILEPATH"
|
108
118
|
fi
|
109
119
|
```
|
110
120
|
|
111
|
-
|
121
|
+
You can also make one for annotating only the lines you have marked.
|
122
|
+
I named it "seeing is believing annotate marked lines"
|
123
|
+
|
124
|
+
```shell
|
125
|
+
#!/bin/bash
|
126
|
+
|
127
|
+
# set result length because TextMate has difficulty displaying long lines
|
128
|
+
default_options=""
|
129
|
+
default_options="$default_options --xmpfilter-style"
|
130
|
+
default_options="$default_options -Ku"
|
131
|
+
default_options="$default_options --result-length 200"
|
132
|
+
default_options="$default_options --alignment-strategy chunk"
|
133
|
+
default_options="$default_options --timeout 12"
|
112
134
|
|
113
|
-
|
135
|
+
if [ -z "$TM_FILEPATH" ]; then
|
136
|
+
"${TM_RUBY}" -S seeing_is_believing $default_options
|
137
|
+
else
|
138
|
+
"${TM_RUBY}" -S seeing_is_believing $default_options --as "$TM_FILEPATH"
|
139
|
+
fi
|
140
|
+
```
|
114
141
|
|
115
|
-
|
142
|
+
And you'll probably want one to clean out the outpt
|
116
143
|
|
117
144
|
```shell
|
145
|
+
#!/bin/bash
|
118
146
|
"${TM_RUBY}" -S seeing_is_believing -Ku --clean
|
119
147
|
```
|
120
148
|
|
149
|
+
You can bind them to whatever keys you want, but I'll recomend (for consistency with what I chose for the Sublime bundle)
|
150
|
+
* annotate all lines -> Command Option b
|
151
|
+
* annotate marked lines -> Command Option n
|
152
|
+
* remove annotations -> Command Option v
|
153
|
+
|
121
154
|
Emacs Integration
|
122
155
|
=================
|
123
156
|
|
@@ -146,21 +179,23 @@ Known Issues
|
|
146
179
|
Todo
|
147
180
|
====
|
148
181
|
|
149
|
-
*
|
150
|
-
*
|
151
|
-
* Update TextMate examples to use same keys as sublime, add xmpfilter option on cmd+opt+N
|
152
|
-
* How about if begin/rescue/end was able to record the result on the rescue section
|
153
|
-
* Check how begin/rescue/end with multiple rescue blocks works
|
154
|
-
* What about recording the result of a line inside of a string interpolation, e.g. "a#{\n1\n}b" could record line 2 is 1 and line 3 is "a\n1\nb"
|
155
|
-
* Be able to clean an invalid file (used to be able to do this, but parser can't identify comments in an invalid file the way that I'm currently using it, cuke is still there, marked as @not-implemented)
|
156
|
-
* Add a flag to allow you to just get the results so that it can be easily used without a Ruby runtime
|
182
|
+
* Sublime: Merge xmpfilter option into main after 2.0 release
|
183
|
+
* Make TextMate 1 and 2 bundles
|
157
184
|
* Go through each cuke and spec, implementing however many not-implemented ones that we can
|
158
|
-
* Check %w and all the others
|
159
|
-
* Add a --shebang flag
|
160
185
|
* Make sure the examples in this readme all still make sense (mountain berry fields?)
|
161
|
-
* uhm, can we wrap the parser setup code in one place? `ack Parser::Source::Buffer`
|
162
|
-
* Make the fucking debugger not lazy
|
163
186
|
* Go through Peter's email about how to make the use of Parser better
|
187
|
+
* Make a new video
|
188
|
+
* Add versions to the debugging output
|
189
|
+
* Shorten the debugging output
|
190
|
+
|
191
|
+
Shit that will probably never get done (or if it does, won't be until after 2.0)
|
192
|
+
================================================================================
|
193
|
+
|
194
|
+
* How about if begin/rescue/end was able to record the result on the rescue section
|
195
|
+
* What about recording the result of a line inside of a string interpolation, e.g. "a#{\n1\n}b" could record line 2 is 1 and line 3 is "a\n1\nb"
|
196
|
+
* Add a flag to allow you to just get the results so that it can be easily used without a Ruby runtime (difficult in that its unclear how to separate line output from stdout, stderr, exit status, exceptions, etc. Maybe just serialize the result as JSON?)
|
197
|
+
* Be able to clean an invalid file (used to be able to do this, but parser can't identify comments in an invalid file the way that I'm currently using it, cuke is still there, marked as @not-implemented)
|
198
|
+
* If given a file with a unicode character, but not set unicode, inform the user
|
164
199
|
|
165
200
|
License
|
166
201
|
=======
|
data/features/flags.feature
CHANGED
@@ -507,3 +507,21 @@ Feature: Using flags
|
|
507
507
|
1# 123
|
508
508
|
2 # => 2
|
509
509
|
"""
|
510
|
+
|
511
|
+
Scenario: --shebang
|
512
|
+
Given the file "fake_ruby":
|
513
|
+
"""
|
514
|
+
#!/usr/bin/env ruby
|
515
|
+
# yes, this uses knowledge of where the proving grounds is
|
516
|
+
$LOAD_PATH.unshift File.expand_path "{{Haiti.config.proving_grounds_dir}}/../lib", __FILE__
|
517
|
+
|
518
|
+
require 'seeing_is_believing'
|
519
|
+
result = SeeingIsBelieving::Result.new
|
520
|
+
result.record_result(1, /omg/)
|
521
|
+
|
522
|
+
require 'yaml'
|
523
|
+
puts YAML.dump result
|
524
|
+
"""
|
525
|
+
When I run "chmod +x fake_ruby"
|
526
|
+
When I run "seeing_is_believing -e 123 --shebang ./fake_ruby"
|
527
|
+
Then stdout is "123 # => /omg/"
|
@@ -26,13 +26,14 @@ class SeeingIsBelieving
|
|
26
26
|
self.options = options
|
27
27
|
self.body = CleanBody.call uncleaned_body, !xmpfilter_style
|
28
28
|
self.results = SeeingIsBelieving.call body,
|
29
|
-
filename:
|
30
|
-
require:
|
31
|
-
load_path:
|
32
|
-
encoding:
|
33
|
-
stdin:
|
34
|
-
timeout:
|
35
|
-
debugger:
|
29
|
+
filename: (options[:as] || options[:filename]),
|
30
|
+
require: options[:require],
|
31
|
+
load_path: options[:load_path],
|
32
|
+
encoding: options[:encoding],
|
33
|
+
stdin: options[:stdin],
|
34
|
+
timeout: options[:timeout],
|
35
|
+
debugger: debugger,
|
36
|
+
ruby_executable: options[:shebang]
|
36
37
|
end
|
37
38
|
|
38
39
|
def call
|
@@ -81,11 +82,8 @@ class SeeingIsBelieving
|
|
81
82
|
new_body << output
|
82
83
|
end
|
83
84
|
|
84
|
-
|
85
|
-
|
86
|
-
else
|
87
|
-
new_body
|
88
|
-
end
|
85
|
+
debugger.context "OUTPUT"
|
86
|
+
new_body
|
89
87
|
end
|
90
88
|
end
|
91
89
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# removes annotations
|
4
4
|
# only removes "# =>" when should_clean_values is false
|
5
5
|
|
6
|
-
require '
|
6
|
+
require 'seeing_is_believing/parser_helpers'
|
7
7
|
|
8
8
|
class SeeingIsBelieving
|
9
9
|
class Binary
|
@@ -18,11 +18,7 @@ class SeeingIsBelieving
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def call
|
21
|
-
buffer
|
22
|
-
buffer.source = code
|
23
|
-
parser = Parser::CurrentRuby.new
|
24
|
-
rewriter = Parser::Source::Rewriter.new(buffer)
|
25
|
-
ast, comments = parser.parse_with_comments(buffer)
|
21
|
+
buffer, parser, rewriter, ast, comments = ParserHelpers.initialize_parser code, 'strip_comments'
|
26
22
|
removed_comments = { result: [], exception: [], stdout: [], stderr: [] }
|
27
23
|
|
28
24
|
comments.each do |comment|
|
@@ -1,15 +1,19 @@
|
|
1
|
-
require '
|
1
|
+
require 'seeing_is_believing/parser_helpers'
|
2
2
|
|
3
3
|
class SeeingIsBelieving
|
4
4
|
class Binary
|
5
|
-
|
6
5
|
class CommentableLines
|
6
|
+
|
7
|
+
include ParserHelpers
|
8
|
+
|
7
9
|
def self.call(code)
|
8
10
|
new(code).call
|
9
11
|
end
|
10
12
|
|
11
13
|
def initialize(code)
|
12
14
|
self.code = code
|
15
|
+
self.buffer, self.parser, self.rewriter, self.root, self.comments =
|
16
|
+
initialize_parser(code, 'strip_comments')
|
13
17
|
end
|
14
18
|
|
15
19
|
def call
|
@@ -23,37 +27,12 @@ class SeeingIsBelieving
|
|
23
27
|
end
|
24
28
|
end
|
25
29
|
|
26
|
-
|
27
|
-
@buffer ||= Parser::Source::Buffer.new("strip_comments").tap { |b| b.source = code }
|
28
|
-
end
|
29
|
-
|
30
|
-
def rewriter
|
31
|
-
@rewriter ||= Parser::Source::Rewriter.new(buffer)
|
32
|
-
end
|
30
|
+
attr_reader :buffer, :rewriter
|
33
31
|
|
34
32
|
private
|
35
33
|
|
36
|
-
|
37
|
-
|
38
|
-
def parser
|
39
|
-
@parser ||= Parser::CurrentRuby.new
|
40
|
-
end
|
41
|
-
|
42
|
-
def root
|
43
|
-
parse!
|
44
|
-
@root
|
45
|
-
end
|
46
|
-
|
47
|
-
def comments
|
48
|
-
parse!
|
49
|
-
@comments
|
50
|
-
end
|
51
|
-
|
52
|
-
|
53
|
-
def parse!
|
54
|
-
return if @root
|
55
|
-
@root, @comments = parser.parse_with_comments(buffer)
|
56
|
-
end
|
34
|
+
attr_writer :buffer, :rewriter
|
35
|
+
attr_accessor :code, :parser, :root, :comments
|
57
36
|
|
58
37
|
def line_nums_to_last_index_and_col(buffer)
|
59
38
|
line_num_to_indexes = code.each_char
|
@@ -126,19 +105,6 @@ class SeeingIsBelieving
|
|
126
105
|
end
|
127
106
|
end
|
128
107
|
|
129
|
-
# copy/pasted from wrap_expressions
|
130
|
-
def heredoc?(ast)
|
131
|
-
# some strings are fucking weird.
|
132
|
-
# e.g. the "1" in `%w[1]` returns nil for ast.location.begin
|
133
|
-
# and `__FILE__` is a string whose location is a Parser::Source::Map instead of a Parser::Source::Map::Collection, so it has no #begin
|
134
|
-
ast.kind_of?(Parser::AST::Node) &&
|
135
|
-
(ast.type == :dstr || ast.type == :str) &&
|
136
|
-
(location = ast.location) &&
|
137
|
-
(location.respond_to?(:begin)) &&
|
138
|
-
(the_begin = location.begin) &&
|
139
|
-
(the_begin.source =~ /^\<\<-?/)
|
140
|
-
end
|
141
|
-
|
142
108
|
def remove_lines_after_data_segment(line_num_to_indexes)
|
143
109
|
data_segment_line, _ = line_num_to_indexes.find do |line_number, (end_index, col)|
|
144
110
|
if end_index == 7
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require 'stringio'
|
2
4
|
require 'seeing_is_believing/version'
|
3
5
|
require 'seeing_is_believing/debugger'
|
@@ -7,16 +9,15 @@ require 'seeing_is_believing/binary/align_chunk'
|
|
7
9
|
|
8
10
|
class SeeingIsBelieving
|
9
11
|
class Binary
|
10
|
-
class
|
11
|
-
def self.
|
12
|
-
new(args).call
|
12
|
+
class ParseArgs
|
13
|
+
def self.call(args, outstream)
|
14
|
+
new(args, outstream).call
|
13
15
|
end
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
def initialize(args)
|
17
|
+
def initialize(args, outstream)
|
18
18
|
self.args = args
|
19
19
|
self.filenames = []
|
20
|
+
self.outstream = outstream
|
20
21
|
end
|
21
22
|
|
22
23
|
def call
|
@@ -28,16 +29,17 @@ class SeeingIsBelieving
|
|
28
29
|
when '-v', '--version' then options[:version] = true
|
29
30
|
when '-x', '--xmpfilter-style' then options[:xmpfilter_style] = true
|
30
31
|
when '-i', '--inherit-exit-status' then options[:inherit_exit_status] = true
|
31
|
-
when '-g', '--debug' then options[:debugger] = Debugger.new(
|
32
|
+
when '-g', '--debug' then options[:debugger] = Debugger.new(stream: outstream, colour: true)
|
32
33
|
when '-l', '--start-line' then extract_positive_int_for :start_line, arg
|
33
34
|
when '-L', '--end-line' then extract_positive_int_for :end_line, arg
|
34
35
|
when '-d', '--line-length' then extract_positive_int_for :max_line_length, arg
|
35
36
|
when '-D', '--result-length' then extract_positive_int_for :max_result_length, arg
|
36
37
|
when '-t', '--timeout' then extract_non_negative_float_for :timeout, arg
|
37
|
-
when '-r', '--require' then next_arg("#{arg} expected a filename as the following argument but did not see one")
|
38
|
-
when '-I', '--load-path' then next_arg("#{arg} expected a directory as the following argument but did not see one")
|
39
|
-
when '-e', '--program' then next_arg("#{arg} expected a program as the following argument but did not see one")
|
40
|
-
when '-a', '--as' then next_arg("#{arg} expected a filename as the following argument but did not see one")
|
38
|
+
when '-r', '--require' then next_arg("#{arg} expected a filename as the following argument but did not see one") { |filename| options[:require] << filename }
|
39
|
+
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 }
|
40
|
+
when '-e', '--program' then next_arg("#{arg} expected a program as the following argument but did not see one") { |program| options[:program] = program }
|
41
|
+
when '-a', '--as' then next_arg("#{arg} expected a filename as the following argument but did not see one") { |filename| options[:as] = filename }
|
42
|
+
when '--shebang' then next_arg("#{arg} expects a ruby executable as the following argument but did not see one") { |executable| options[:shebang] = executable }
|
41
43
|
when '-s', '--alignment-strategy' then extract_alignment_strategy
|
42
44
|
when /\A-K(.+)/ then options[:encoding] = $1
|
43
45
|
when '-K', '--encoding' then next_arg("#{arg} expects an encoding, see `man ruby` for possibile values") { |encoding| options[:encoding] = encoding }
|
@@ -54,7 +56,8 @@ class SeeingIsBelieving
|
|
54
56
|
|
55
57
|
private
|
56
58
|
|
57
|
-
attr_accessor :filenames
|
59
|
+
attr_accessor :filenames, :args, :outstream
|
60
|
+
|
58
61
|
|
59
62
|
def normalize_and_validate
|
60
63
|
if 1 < filenames.size
|
@@ -70,7 +73,7 @@ class SeeingIsBelieving
|
|
70
73
|
|
71
74
|
def options
|
72
75
|
@options ||= {
|
73
|
-
debugger: Debugger.new(
|
76
|
+
debugger: Debugger.new(stream: nil),
|
74
77
|
version: false,
|
75
78
|
clean: false,
|
76
79
|
xmpfilter_style: false,
|
@@ -86,6 +89,7 @@ class SeeingIsBelieving
|
|
86
89
|
require: [],
|
87
90
|
load_path: [],
|
88
91
|
alignment_strategy: AlignChunk,
|
92
|
+
shebang: 'ruby',
|
89
93
|
}
|
90
94
|
end
|
91
95
|
|
@@ -130,7 +134,7 @@ class SeeingIsBelieving
|
|
130
134
|
|
131
135
|
end
|
132
136
|
|
133
|
-
def
|
137
|
+
def ParseArgs.help_screen
|
134
138
|
<<HELP_SCREEN
|
135
139
|
Usage: seeing_is_believing [options] [filename]
|
136
140
|
|
@@ -156,8 +160,92 @@ Usage: seeing_is_believing [options] [filename]
|
|
156
160
|
-g, --debug # print debugging information (useful if program is fucking up, or if you want to brag)
|
157
161
|
-x, --xmpfilter-style # annotate marked lines instead of every line
|
158
162
|
-i, --inherit-exit-status # exit with the exit status of the program being eval
|
163
|
+
--shebang ruby-executable # if you want SiB to use some ruby other than the one in the path
|
159
164
|
-v, --version # print the version (#{VERSION})
|
160
165
|
-h, --help # this help screen
|
166
|
+
|
167
|
+
Examples: A few examples, for a more comprehensive set of examples, check out features/flags.feature
|
168
|
+
|
169
|
+
Run the file f.rb
|
170
|
+
$ echo __FILE__ > f.rb; seeing_is_believing f.rb
|
171
|
+
__FILE__ # => "f.rb"
|
172
|
+
|
173
|
+
Aligning comments
|
174
|
+
$ ruby -e 'puts "123\\n4\\n\\n567890"' > f.rb
|
175
|
+
|
176
|
+
|
177
|
+
$ seeing_is_believing f.rb -s line
|
178
|
+
123 # => 123
|
179
|
+
4 # => 4
|
180
|
+
|
181
|
+
567890 # => 567890
|
182
|
+
|
183
|
+
|
184
|
+
$ seeing_is_believing f.rb -s chunk
|
185
|
+
123 # => 123
|
186
|
+
4 # => 4
|
187
|
+
|
188
|
+
567890 # => 567890
|
189
|
+
|
190
|
+
|
191
|
+
$ seeing_is_believing f.rb -s file
|
192
|
+
123 # => 123
|
193
|
+
4 # => 4
|
194
|
+
|
195
|
+
567890 # => 567890
|
196
|
+
|
197
|
+
Run against standard input
|
198
|
+
$ echo '3.times { |i| puts i }' | seeing_is_believing
|
199
|
+
2.times { |i| puts i } # => 2
|
200
|
+
|
201
|
+
# >> 0
|
202
|
+
# >> 1
|
203
|
+
|
204
|
+
Run against a library you're working on by fixing the load path
|
205
|
+
$ seeing_is_believing -I lib f.rb
|
206
|
+
|
207
|
+
Load up some library (can be used in tandem with -I)
|
208
|
+
$ seeing_is_believing -r pp -e 'pp [[*1..15],[*15..30]]; nil'
|
209
|
+
pp [[*1..15],[*15..30]]; nil # => nil
|
210
|
+
|
211
|
+
# >> [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
|
212
|
+
# >> [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]]
|
213
|
+
|
214
|
+
Only update the lines you've marked
|
215
|
+
$ ruby -e 'puts "1\\n2 # =>\\n3"' | seeing_is_believing -x
|
216
|
+
1
|
217
|
+
2 # => 2
|
218
|
+
3
|
219
|
+
|
220
|
+
Set a timeout (especially useful if running via an editor)
|
221
|
+
$ seeing_is_believing -e 'loop { sleep 1 }' -t 3
|
222
|
+
Timeout Error after 3.0 seconds!
|
223
|
+
|
224
|
+
Set the encoding to utf-8
|
225
|
+
$ seeing_is_believing -Ku -e '"⛄ "'
|
226
|
+
"⛄ " # => "⛄ "
|
227
|
+
|
228
|
+
The exit status will be 1 if the error is displayable inline
|
229
|
+
$ seeing_is_believing -e 'raise "omg"'; echo $?
|
230
|
+
raise "omg" # ~> RuntimeError: omg
|
231
|
+
1
|
232
|
+
|
233
|
+
The exit status will be 2 if the error is not displayable
|
234
|
+
$ seeing_is_believing -e 'a='; echo $status
|
235
|
+
-:1: syntax error, unexpected $end
|
236
|
+
2
|
237
|
+
|
238
|
+
Run with previous output
|
239
|
+
$ echo "1+1 # => old-value" | seeing_is_believing
|
240
|
+
1+1 # => 2
|
241
|
+
|
242
|
+
$ echo "1+1 # => old-value" | seeing_is_believing --clean
|
243
|
+
1+1
|
244
|
+
|
245
|
+
If your Ruby binary is named something else (e.g. ruby2.0)
|
246
|
+
$ ruby2.0 -S seeing_is_believing --shebang ruby2.0 -e '123'
|
247
|
+
123 # => 123
|
248
|
+
|
161
249
|
HELP_SCREEN
|
162
250
|
end
|
163
251
|
end
|
@@ -1,14 +1,10 @@
|
|
1
|
-
require '
|
1
|
+
require 'seeing_is_believing/parser_helpers'
|
2
2
|
|
3
3
|
class SeeingIsBelieving
|
4
4
|
class Binary
|
5
5
|
module RewriteComments
|
6
6
|
def self.call(code, &mapping)
|
7
|
-
buffer
|
8
|
-
buffer.source = code
|
9
|
-
parser = Parser::CurrentRuby.new
|
10
|
-
rewriter = Parser::Source::Rewriter.new(buffer)
|
11
|
-
ast, comments = parser.parse_with_comments(buffer)
|
7
|
+
buffer, parser, rewriter, ast, comments = ParserHelpers.initialize_parser code, 'strip_comments'
|
12
8
|
|
13
9
|
comments.each do |comment|
|
14
10
|
next unless comment.type == :inline
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'seeing_is_believing'
|
2
|
-
require 'seeing_is_believing/binary/
|
2
|
+
require 'seeing_is_believing/binary/parse_args'
|
3
3
|
require 'seeing_is_believing/binary/add_annotations'
|
4
4
|
require 'seeing_is_believing/binary/clean_body'
|
5
5
|
require 'timeout'
|
@@ -52,7 +52,7 @@ class SeeingIsBelieving
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def parse_flags
|
55
|
-
self.flags =
|
55
|
+
self.flags = ParseArgs.call argv, stdout
|
56
56
|
end
|
57
57
|
|
58
58
|
def has_filename?
|
@@ -86,7 +86,11 @@ class SeeingIsBelieving
|
|
86
86
|
end
|
87
87
|
|
88
88
|
def print_unexpected_error
|
89
|
-
|
89
|
+
if unexpected_exception.kind_of? BugInSib
|
90
|
+
stderr.puts unexpected_exception.message
|
91
|
+
else
|
92
|
+
stderr.puts unexpected_exception.class, unexpected_exception.message, "", unexpected_exception.backtrace
|
93
|
+
end
|
90
94
|
end
|
91
95
|
|
92
96
|
def printer
|
@@ -138,7 +142,7 @@ class SeeingIsBelieving
|
|
138
142
|
end
|
139
143
|
|
140
144
|
def syntax_error_notice
|
141
|
-
out, err, syntax_status = Open3.capture3
|
145
|
+
out, err, syntax_status = Open3.capture3 flags[:shebang], '-c', stdin_data: body
|
142
146
|
return err unless syntax_status.success?
|
143
147
|
end
|
144
148
|
|
@@ -5,32 +5,27 @@ class SeeingIsBelieving
|
|
5
5
|
RESET_COLOUR = "\e[0m"
|
6
6
|
|
7
7
|
def initialize(options={})
|
8
|
-
@
|
9
|
-
@
|
10
|
-
@coloured = options.fetch :colour, false
|
11
|
-
end
|
12
|
-
|
13
|
-
def enabled?
|
14
|
-
@enabled
|
8
|
+
@coloured = options[:colour]
|
9
|
+
@stream = options[:stream]
|
15
10
|
end
|
16
11
|
|
17
12
|
def coloured?
|
18
13
|
@coloured
|
19
14
|
end
|
20
15
|
|
16
|
+
attr_reader :stream
|
17
|
+
alias enabled? stream
|
18
|
+
|
21
19
|
def context(name, &block)
|
22
|
-
|
20
|
+
if stream
|
21
|
+
stream << CONTEXT_COLOUR if coloured?
|
22
|
+
stream << "#{name}:"
|
23
|
+
stream << RESET_COLOUR if coloured?
|
24
|
+
stream << "\n"
|
25
|
+
stream << block.call.to_s << "\n" if block
|
26
|
+
end
|
23
27
|
self
|
24
28
|
end
|
25
29
|
|
26
|
-
def to_s
|
27
|
-
@contexts.map { |name, values|
|
28
|
-
string = ""
|
29
|
-
string << CONTEXT_COLOUR if coloured?
|
30
|
-
string << "#{name}:"
|
31
|
-
string << RESET_COLOUR if coloured?
|
32
|
-
string << "\n#{values.join "\n"}\n"
|
33
|
-
}.join("\n")
|
34
|
-
end
|
35
30
|
end
|
36
31
|
end
|
@@ -11,4 +11,18 @@ class SeeingIsBelieving
|
|
11
11
|
" then delete TEMPFILE. Otherwise rename TEMPFILE to FILE."
|
12
12
|
end
|
13
13
|
end
|
14
|
+
|
15
|
+
class BugInSib < SeeingIsBelievingError
|
16
|
+
def initialize(error)
|
17
|
+
require 'parser/version'
|
18
|
+
require 'seeing_is_believing/version'
|
19
|
+
|
20
|
+
super "It blew up >.< Please log an issue at: https://github.com/JoshCheek/seeing_is_believing/issues\n"\
|
21
|
+
"SeeingIsBelieving::VERSION #{SeeingIsBelieving::VERSION.inspect}\n"\
|
22
|
+
"Parser::VERSION #{Parser::VERSION.inspect}\n"\
|
23
|
+
"RUBY_VERSION #{RUBY_VERSION.inspect}\n"\
|
24
|
+
"ENV['RUBY_VERSION'] #{ENV['RUBY_VERSION'].inspect}\n"\
|
25
|
+
"Also include the source code of program that caused this behaviour."
|
26
|
+
end
|
27
|
+
end
|
14
28
|
end
|
@@ -18,22 +18,24 @@ require 'stringio'
|
|
18
18
|
require 'fileutils'
|
19
19
|
require 'seeing_is_believing/error'
|
20
20
|
require 'seeing_is_believing/result'
|
21
|
+
require 'seeing_is_believing/debugger'
|
21
22
|
require 'seeing_is_believing/hard_core_ensure'
|
22
23
|
|
23
24
|
class SeeingIsBelieving
|
24
25
|
class EvaluateByMovingFiles
|
25
|
-
attr_accessor :program, :filename, :
|
26
|
+
attr_accessor :program, :filename, :input_stream, :matrix_filename, :require_flags, :load_path_flags, :encoding, :timeout, :ruby_executable, :debugger
|
26
27
|
|
27
28
|
def initialize(program, filename, options={})
|
28
29
|
self.program = program
|
29
30
|
self.filename = filename
|
30
|
-
self.error_stream = options.fetch :error_stream, $stderr # hmm, not really liking the global here
|
31
31
|
self.input_stream = options.fetch :input_stream, StringIO.new('')
|
32
32
|
self.matrix_filename = options[:matrix_filename] || 'seeing_is_believing/the_matrix'
|
33
33
|
self.require_flags = options.fetch(:require, []).map { |filename| ['-r', filename] }.flatten
|
34
34
|
self.load_path_flags = options.fetch(:load_path, []).map { |dir| ['-I', dir] }.flatten
|
35
35
|
self.encoding = options.fetch :encoding, nil
|
36
36
|
self.timeout = options[:timeout]
|
37
|
+
self.ruby_executable = options.fetch :ruby_executable, 'ruby'
|
38
|
+
self.debugger = options.fetch :debugger, Debugger.new(stream: nil)
|
37
39
|
end
|
38
40
|
|
39
41
|
def call
|
@@ -47,9 +49,9 @@ class SeeingIsBelieving
|
|
47
49
|
deserialize_result.tap { |result| fail if result.bug_in_sib? }
|
48
50
|
# Okay, really, I should wrap this in another exception and raise it on up,
|
49
51
|
# but for now, I'm feeling a little lazy and am not going to do it
|
50
|
-
rescue Exception
|
51
|
-
|
52
|
-
raise
|
52
|
+
rescue Exception => error
|
53
|
+
error = wrap_error error if error_implies_bug_in_sib? error
|
54
|
+
raise error
|
53
55
|
end
|
54
56
|
},
|
55
57
|
ensure: -> {
|
@@ -117,7 +119,7 @@ class SeeingIsBelieving
|
|
117
119
|
end
|
118
120
|
|
119
121
|
def popen_args
|
120
|
-
[
|
122
|
+
[ruby_executable,
|
121
123
|
'-W0', # no warnings (b/c I hijack STDOUT/STDERR)
|
122
124
|
*(encoding ? ["-K#{encoding}"] : []), # allow the encoding to be set
|
123
125
|
'-I', File.expand_path('../..', __FILE__), # add lib to the load path
|
@@ -135,17 +137,14 @@ class SeeingIsBelieving
|
|
135
137
|
YAML.load stdout
|
136
138
|
end
|
137
139
|
|
138
|
-
def
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
error_stream.puts "Stderr: #{stderr.inspect}"
|
147
|
-
error_stream.puts
|
148
|
-
error_stream.puts "Status: #{exitstatus.inspect}"
|
140
|
+
def wrap_error(error)
|
141
|
+
debugger.context "Program could not be evaluated" do
|
142
|
+
"Program: #{program.inspect.chomp}\n\n"\
|
143
|
+
"Stdout: #{stdout.inspect.chomp}\n\n"\
|
144
|
+
"Stderr: #{stderr.inspect.chomp}\n\n"\
|
145
|
+
"Status: #{exitstatus.inspect.chomp}\n"
|
146
|
+
end
|
147
|
+
BugInSib.new error
|
149
148
|
end
|
150
149
|
end
|
151
150
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'parser/current'
|
2
|
+
class SeeingIsBelieving
|
3
|
+
module ParserHelpers
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def initialize_parser(code, name)
|
7
|
+
buffer = Parser::Source::Buffer.new(name)
|
8
|
+
buffer.source = code
|
9
|
+
parser = Parser::CurrentRuby.new
|
10
|
+
root, comments = parser.parse_with_comments buffer
|
11
|
+
rewriter = Parser::Source::Rewriter.new buffer
|
12
|
+
[buffer, parser, rewriter, root, comments]
|
13
|
+
end
|
14
|
+
|
15
|
+
# this is the scardest fucking method I think I've ever written.
|
16
|
+
# *anything* can go wrong!
|
17
|
+
def heredoc?(ast)
|
18
|
+
# some strings are fucking weird.
|
19
|
+
# e.g. the "1" in `%w[1]` returns nil for ast.location.begin
|
20
|
+
# and `__FILE__` is a string whose location is a Parser::Source::Map instead of a Parser::Source::Map::Collection, so it has no #begin
|
21
|
+
ast.kind_of?(Parser::AST::Node) &&
|
22
|
+
(ast.type == :dstr || ast.type == :str) &&
|
23
|
+
(location = ast.location) &&
|
24
|
+
(location.respond_to?(:begin)) &&
|
25
|
+
(the_begin = location.begin) &&
|
26
|
+
(the_begin.source =~ /^\<\<-?/)
|
27
|
+
end
|
28
|
+
|
29
|
+
def void_value?(ast)
|
30
|
+
case ast && ast.type
|
31
|
+
when :begin, :kwbegin, :resbody
|
32
|
+
void_value?(ast.children[-1])
|
33
|
+
when :rescue, :ensure
|
34
|
+
ast.children.any? { |child| void_value? child }
|
35
|
+
when :if
|
36
|
+
void_value?(ast.children[1]) || void_value?(ast.children[2])
|
37
|
+
when :return, :next, :redo, :retry, :break
|
38
|
+
true
|
39
|
+
else
|
40
|
+
false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def heredoc_hack(ast)
|
45
|
+
return ast unless heredoc? ast
|
46
|
+
Parser::AST::Node.new :str,
|
47
|
+
[],
|
48
|
+
location: Parser::Source::Map.new(ast.location.begin)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'parser/current'
|
2
|
+
require 'seeing_is_believing/parser_helpers'
|
2
3
|
|
3
4
|
# hack rewriter to apply insertions in stable order
|
4
5
|
# until https://github.com/whitequark/parser/pull/102 gets released
|
@@ -31,6 +32,9 @@ end
|
|
31
32
|
# https://github.com/whitequark/parser/blob/master/doc/AST_FORMAT.md
|
32
33
|
class SeeingIsBelieving
|
33
34
|
class WrapExpressions
|
35
|
+
|
36
|
+
include ParserHelpers
|
37
|
+
|
34
38
|
def self.call(program, wrappings)
|
35
39
|
new(program, wrappings).call
|
36
40
|
end
|
@@ -41,10 +45,7 @@ class SeeingIsBelieving
|
|
41
45
|
self.after_all = wrappings.fetch :after_all, ''.freeze
|
42
46
|
self.before_each = wrappings.fetch :before_each, -> * { '' }
|
43
47
|
self.after_each = wrappings.fetch :after_each, -> * { '' }
|
44
|
-
self.buffer
|
45
|
-
buffer.source = program
|
46
|
-
self.root = Parser::CurrentRuby.new.parse buffer
|
47
|
-
self.rewriter = Parser::Source::Rewriter.new buffer
|
48
|
+
self.buffer, _, self.rewriter, self.root, _ = initialize_parser(program, 'program-without-annotations')
|
48
49
|
self.wrappings = {}
|
49
50
|
rescue Parser::SyntaxError => e
|
50
51
|
raise ::SyntaxError, e.message
|
@@ -190,6 +191,13 @@ class SeeingIsBelieving
|
|
190
191
|
end_pos += 1
|
191
192
|
end
|
192
193
|
|
194
|
+
# target is a heredoc, so we can't trust the expression
|
195
|
+
# but method has parens, so we can't trust the last arg
|
196
|
+
elsif heredoc?(target) && last_arg && buffer.source[ast.location.selector.end_pos] == '('
|
197
|
+
end_pos = last_arg.location.expression.end_pos
|
198
|
+
end_pos += 1 until buffer.source[end_pos] == ')'
|
199
|
+
end_pos += 1
|
200
|
+
|
193
201
|
elsif heredoc?(target) && last_arg
|
194
202
|
end_pos = last_arg.location.expression.end_pos
|
195
203
|
|
@@ -238,51 +246,6 @@ class SeeingIsBelieving
|
|
238
246
|
add_to_wrappings ast
|
239
247
|
add_children ast
|
240
248
|
end
|
241
|
-
rescue
|
242
|
-
# TODO: delete this rescue block once things get stabler
|
243
|
-
puts ast.type
|
244
|
-
puts $!
|
245
|
-
require "pry"
|
246
|
-
binding.pry
|
247
|
-
raise
|
248
|
-
end
|
249
|
-
|
250
|
-
def heredoc_hack(ast)
|
251
|
-
return ast unless heredoc? ast
|
252
|
-
Parser::AST::Node.new :str,
|
253
|
-
[],
|
254
|
-
location: Parser::Source::Map.new(ast.location.begin)
|
255
|
-
end
|
256
|
-
|
257
|
-
# this is the scardest fucking method I think I've ever written.
|
258
|
-
# *anything* can go wrong!
|
259
|
-
#
|
260
|
-
# !!NOTE!! This method is copy/pasted into Binary::CommentLines
|
261
|
-
def heredoc?(ast)
|
262
|
-
# some strings are fucking weird.
|
263
|
-
# e.g. the "1" in `%w[1]` returns nil for ast.location.begin
|
264
|
-
# and `__FILE__` is a string whose location is a Parser::Source::Map instead of a Parser::Source::Map::Collection, so it has no #begin
|
265
|
-
ast.kind_of?(Parser::AST::Node) &&
|
266
|
-
(ast.type == :dstr || ast.type == :str) &&
|
267
|
-
(location = ast.location) &&
|
268
|
-
(location.respond_to?(:begin)) &&
|
269
|
-
(the_begin = location.begin) &&
|
270
|
-
(the_begin.source =~ /^\<\<-?/)
|
271
|
-
end
|
272
|
-
|
273
|
-
def void_value?(ast)
|
274
|
-
case ast && ast.type
|
275
|
-
when :begin, :kwbegin, :resbody
|
276
|
-
void_value?(ast.children[-1])
|
277
|
-
when :rescue, :ensure
|
278
|
-
ast.children.any? { |child| void_value? child }
|
279
|
-
when :if
|
280
|
-
void_value?(ast.children[1]) || void_value?(ast.children[2])
|
281
|
-
when :return, :next, :redo, :retry, :break
|
282
|
-
true
|
283
|
-
else
|
284
|
-
false
|
285
|
-
end
|
286
249
|
end
|
287
250
|
end
|
288
251
|
end
|
data/lib/seeing_is_believing.rb
CHANGED
@@ -25,7 +25,8 @@ class SeeingIsBelieving
|
|
25
25
|
@load_path = options.fetch :load_path, []
|
26
26
|
@encoding = options.fetch :encoding, nil
|
27
27
|
@timeout = options[:timeout]
|
28
|
-
@debugger = options.fetch :debugger, Debugger.new(
|
28
|
+
@debugger = options.fetch :debugger, Debugger.new(stream: nil)
|
29
|
+
@ruby_executable = options.fetch :ruby_executable, 'ruby'
|
29
30
|
end
|
30
31
|
|
31
32
|
def call
|
@@ -70,7 +71,9 @@ class SeeingIsBelieving
|
|
70
71
|
require: @require,
|
71
72
|
load_path: @load_path,
|
72
73
|
encoding: @encoding,
|
73
|
-
timeout: @timeout
|
74
|
+
timeout: @timeout,
|
75
|
+
ruby_executable: @ruby_executable,
|
76
|
+
debugger: @debugger)
|
74
77
|
.call
|
75
78
|
end
|
76
79
|
end
|
data/seeing_is_believing.gemspec
CHANGED
@@ -19,7 +19,7 @@ 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", "
|
22
|
+
s.add_dependency "parser", "= 2.0.0.pre6"
|
23
23
|
|
24
24
|
s.add_development_dependency "haiti", "~> 0.0.3"
|
25
25
|
s.add_development_dependency "rake", "~> 10.0.3"
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require 'seeing_is_believing/binary/
|
1
|
+
require 'seeing_is_believing/binary/parse_args'
|
2
2
|
|
3
|
-
describe SeeingIsBelieving::Binary::
|
3
|
+
describe SeeingIsBelieving::Binary::ParseArgs do
|
4
4
|
RSpec::Matchers.define :have_error do |error_assertion|
|
5
5
|
match do |options|
|
6
6
|
options[:errors].find do |error|
|
@@ -22,8 +22,8 @@ describe SeeingIsBelieving::Binary::ArgParser do
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
def parse(args)
|
26
|
-
described_class.
|
25
|
+
def parse(args, outstream=nil)
|
26
|
+
described_class.call args, outstream
|
27
27
|
end
|
28
28
|
|
29
29
|
shared_examples 'it requires a positive int argument' do |flags|
|
@@ -336,12 +336,31 @@ describe SeeingIsBelieving::Binary::ArgParser do
|
|
336
336
|
|
337
337
|
describe ':debugger' do
|
338
338
|
it 'defaults to a debugger that is disabled' do
|
339
|
-
parse([])[:debugger].should_not be_enabled
|
339
|
+
parse([], :fake_stream)[:debugger].should_not be_enabled
|
340
340
|
end
|
341
341
|
|
342
342
|
it 'can be enabled with --debug or -g' do
|
343
|
-
parse(['--debug'])[:debugger].should be_enabled
|
344
|
-
parse(['-g'])[:debugger].should be_enabled
|
343
|
+
parse(['--debug'], :fake_stream)[:debugger].should be_enabled
|
344
|
+
parse(['-g'], :fake_stream)[:debugger].should be_enabled
|
345
|
+
end
|
346
|
+
|
347
|
+
it 'sets the stream to the one passed in' do
|
348
|
+
parse(['-g'], :fake_stream)[:debugger].stream.should == :fake_stream
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
describe ':shebang' do
|
353
|
+
it 'defaults to "ruby"' do
|
354
|
+
parse([])[:shebang].should == 'ruby'
|
355
|
+
end
|
356
|
+
|
357
|
+
it 'can be enabled with --shebang' do
|
358
|
+
parse(['--shebang', 'not_ruby'])[:shebang].should == 'not_ruby'
|
359
|
+
end
|
360
|
+
|
361
|
+
it 'sets an error if not given a next arg to execute' do
|
362
|
+
parse([]).should_not have_error /--shebang/
|
363
|
+
parse(['--shebang']).should have_error /--shebang/
|
345
364
|
end
|
346
365
|
end
|
347
366
|
end
|
data/spec/debugger_spec.rb
CHANGED
@@ -1,27 +1,40 @@
|
|
1
1
|
require 'seeing_is_believing/debugger'
|
2
|
+
require 'stringio'
|
2
3
|
|
3
4
|
describe SeeingIsBelieving::Debugger do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
described_class.new(
|
5
|
+
let(:stream) { StringIO.new }
|
6
|
+
|
7
|
+
specify 'is enabled when given a stream' do
|
8
|
+
described_class.new(stream: nil).should_not be_enabled
|
9
|
+
described_class.new(stream: stream).should be_enabled
|
8
10
|
end
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
|
12
|
+
specify 'colour is disabled by default' do
|
13
|
+
described_class.new.should_not be_coloured
|
14
|
+
described_class.new(colour: false).should_not be_coloured
|
15
|
+
described_class.new(colour: true).should be_coloured
|
13
16
|
end
|
14
17
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
context 'when given a steram' do
|
19
|
+
it 'prints the the context and the value of the block' do
|
20
|
+
described_class.new(stream: stream).context('C') { 'V' }
|
21
|
+
stream.string.should == "C:\nV\n"
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'colours the context when colour is set to true' do
|
25
|
+
described_class.new(stream: stream, colour: true).context('C') { 'V' }
|
26
|
+
stream.string.should == "#{described_class::CONTEXT_COLOUR}C:#{described_class::RESET_COLOUR}\nV\n"
|
27
|
+
end
|
21
28
|
end
|
22
29
|
|
23
|
-
|
24
|
-
|
25
|
-
|
30
|
+
context 'when not given a stream' do
|
31
|
+
it 'prints nothing' do
|
32
|
+
described_class.new.context('C') { 'V' }
|
33
|
+
stream.string.should be_empty
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'does not evaluate the blocks' do
|
37
|
+
described_class.new.context('C') { fail }
|
38
|
+
end
|
26
39
|
end
|
27
40
|
end
|
@@ -42,7 +42,7 @@ describe SeeingIsBelieving::EvaluateByMovingFiles do
|
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'uses HardCoreEnsure to move the file back' do
|
45
|
-
evaluator = described_class.new 'PROGRAM', filename
|
45
|
+
evaluator = described_class.new 'PROGRAM', filename
|
46
46
|
File.open(filename, 'w') { |f| f.write 'ORIGINAL' }
|
47
47
|
FileUtils.rm_rf evaluator.temp_filename
|
48
48
|
SeeingIsBelieving::HardCoreEnsure.should_receive(:call) do |options|
|
@@ -64,7 +64,7 @@ describe SeeingIsBelieving::EvaluateByMovingFiles do
|
|
64
64
|
end
|
65
65
|
|
66
66
|
it 'uses HardCoreEnsure to delete the file if it wrote it where one did not previously exist' do
|
67
|
-
evaluator = described_class.new 'PROGRAM', filename
|
67
|
+
evaluator = described_class.new 'PROGRAM', filename
|
68
68
|
FileUtils.rm_rf filename
|
69
69
|
SeeingIsBelieving::HardCoreEnsure.should_receive(:call) do |options|
|
70
70
|
# initial state
|
@@ -100,11 +100,11 @@ describe SeeingIsBelieving::EvaluateByMovingFiles do
|
|
100
100
|
invoke('print "ç"', encoding: 'u').stdout.should == "ç"
|
101
101
|
end
|
102
102
|
|
103
|
-
it 'prints some
|
104
|
-
|
105
|
-
evaluator = described_class.new 'raise "omg"', filename,
|
103
|
+
it 'if it fails, it prints some debugging information and raises an error', t:true do
|
104
|
+
error_stream = StringIO.new
|
105
|
+
evaluator = described_class.new 'raise "omg"', filename, debugger: SeeingIsBelieving::Debugger.new(stream: error_stream)
|
106
106
|
FileUtils.rm_f evaluator.temp_filename
|
107
|
-
expect { evaluator.call }.to raise_error
|
108
|
-
|
107
|
+
expect { evaluator.call }.to raise_error SeeingIsBelieving::BugInSib
|
108
|
+
error_stream.string.should include "Program could not be evaluated"
|
109
109
|
end
|
110
110
|
end
|
@@ -7,8 +7,8 @@ describe SeeingIsBelieving do
|
|
7
7
|
described_class.new(input, options).call
|
8
8
|
end
|
9
9
|
|
10
|
-
def values_for(input)
|
11
|
-
invoke(input).to_a
|
10
|
+
def values_for(input, options={})
|
11
|
+
invoke(input, options).to_a
|
12
12
|
end
|
13
13
|
|
14
14
|
let(:proving_grounds_dir) { File.expand_path '../../proving_grounds', __FILE__ }
|
@@ -296,8 +296,32 @@ describe SeeingIsBelieving do
|
|
296
296
|
['[6, 12]']]
|
297
297
|
end
|
298
298
|
|
299
|
+
it 'can evaluate under a different ruby executable' do
|
300
|
+
Dir.chdir proving_grounds_dir do
|
301
|
+
File.write 'omg-ruby', "#!/usr/bin/env ruby
|
302
|
+
$LOAD_PATH.unshift '#{File.expand_path '../lib', __FILE__}'
|
303
|
+
|
304
|
+
require 'seeing_is_believing'
|
305
|
+
result = SeeingIsBelieving::Result.new
|
306
|
+
result.record_result(1, /omg/)
|
307
|
+
|
308
|
+
require 'yaml'
|
309
|
+
puts YAML.dump result
|
310
|
+
"
|
311
|
+
File.chmod 0755, 'omg-ruby'
|
312
|
+
old_path = ENV['PATH']
|
313
|
+
ENV['PATH'] = "#{proving_grounds_dir}:#{old_path}"
|
314
|
+
begin
|
315
|
+
values_for("1", ruby_executable: 'omg-ruby').should == [["/omg/"]]
|
316
|
+
ensure
|
317
|
+
ENV['PATH'] = old_path
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
299
322
|
context 'when given a debugger' do
|
300
|
-
let(:
|
323
|
+
let(:stream) { StringIO.new }
|
324
|
+
let(:debugger) { SeeingIsBelieving::Debugger.new stream: stream }
|
301
325
|
|
302
326
|
def call
|
303
327
|
invoke "1", debugger: debugger
|
@@ -305,14 +329,14 @@ describe SeeingIsBelieving do
|
|
305
329
|
|
306
330
|
it 'prints the pre-evaluated program' do
|
307
331
|
call
|
308
|
-
|
309
|
-
|
332
|
+
stream.string.should include "TRANSLATED PROGRAM:"
|
333
|
+
stream.string.should include "\nbegin;" # there is more, but we're just interested in showing that it wound up in the stream
|
310
334
|
end
|
311
335
|
|
312
336
|
it 'prints the result' do
|
313
337
|
call
|
314
|
-
|
315
|
-
|
338
|
+
stream.string.should include "RESULT:"
|
339
|
+
stream.string.should include '1=>#<SIB:Line["1"] no exception>'
|
316
340
|
end
|
317
341
|
# should ProgramRewriter have some debug options?
|
318
342
|
end
|
@@ -384,7 +384,6 @@ describe SeeingIsBelieving::WrapExpressions do
|
|
384
384
|
wrap("$a ||= begin\n123\nend").should == "<$a ||= begin\n<123>\nend>"
|
385
385
|
wrap("@@a ||= begin\n123\nend").should == "<@@a ||= begin\n<123>\nend>"
|
386
386
|
wrap("B ||= begin\n123\nend").should == "<B ||= begin\n<123>\nend>"
|
387
|
-
wrap("::B ||= begin\n123\nend").should == "<::B ||= begin\n<123>\nend>"
|
388
387
|
end
|
389
388
|
|
390
389
|
it 'wraps arguments in the assignment' do
|
@@ -630,6 +629,7 @@ describe SeeingIsBelieving::WrapExpressions do
|
|
630
629
|
it 'wraps methods tacked onto the end of heredocs' do
|
631
630
|
wrap("<<A.size\nA").should == "<<<A.size>\nA"
|
632
631
|
wrap("<<A.size 1\nA").should == "<<<A.size 1>\nA"
|
632
|
+
wrap("<<A.size(1)\nA").should == "<<<A.size(1)>\nA"
|
633
633
|
wrap("<<A.whatever <<B\nA\nB").should == "<<<A.whatever <<B>\nA\nB"
|
634
634
|
wrap("<<A.whatever(<<B)\nA\nB").should == "<<<A.whatever(<<B)>\nA\nB"
|
635
635
|
wrap("<<A.size()\nA").should == "<<<A.size()>\nA"
|
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: seeing_is_believing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.beta3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Cheek
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-08-
|
11
|
+
date: 2013-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 2.0.0.pre6
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 2.0.0.pre6
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -121,11 +121,11 @@ files:
|
|
121
121
|
- lib/seeing_is_believing/binary/align_chunk.rb
|
122
122
|
- lib/seeing_is_believing/binary/align_file.rb
|
123
123
|
- lib/seeing_is_believing/binary/align_line.rb
|
124
|
-
- lib/seeing_is_believing/binary/arg_parser.rb
|
125
124
|
- lib/seeing_is_believing/binary/clean_body.rb
|
126
125
|
- lib/seeing_is_believing/binary/comment_formatter.rb
|
127
126
|
- lib/seeing_is_believing/binary/comment_lines.rb
|
128
127
|
- lib/seeing_is_believing/binary/commentable_lines.rb
|
128
|
+
- lib/seeing_is_believing/binary/parse_args.rb
|
129
129
|
- lib/seeing_is_believing/binary/rewrite_comments.rb
|
130
130
|
- lib/seeing_is_believing/debugger.rb
|
131
131
|
- lib/seeing_is_believing/error.rb
|
@@ -133,6 +133,7 @@ files:
|
|
133
133
|
- lib/seeing_is_believing/hard_core_ensure.rb
|
134
134
|
- lib/seeing_is_believing/has_exception.rb
|
135
135
|
- lib/seeing_is_believing/line.rb
|
136
|
+
- lib/seeing_is_believing/parser_helpers.rb
|
136
137
|
- lib/seeing_is_believing/result.rb
|
137
138
|
- lib/seeing_is_believing/the_matrix.rb
|
138
139
|
- lib/seeing_is_believing/version.rb
|