seeing_is_believing 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ desc 'run specs'
2
+ task :spec do
3
+ sh 'rspec -cf d --fail-fast'
4
+ end
5
+
6
+ desc 'run cukes'
7
+ task :cuke do
8
+ sh 'cucumber -t ~@not-implemented -t ~@wip'
9
+ end
10
+
11
+ namespace :cuke do
12
+ desc 'Run work in progress cukes'
13
+ task :wip do
14
+ sh 'cucumber -t @wip'
15
+ end
16
+ end
17
+
18
+ namespace :spec do
19
+ desc 'Run work in progress specs'
20
+ task :wip do
21
+ sh 'rspec -t wip'
22
+ end
23
+ end
24
+
25
+ desc 'Run work in progress specs and cukes'
26
+ task wip: ['spec:wip', 'cuke:wip']
27
+
28
+ desc 'Run all specs and cukes'
29
+ task default: [:spec, :cuke]
@@ -1,17 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  $LOAD_PATH.unshift File.expand_path '../../lib', __FILE__
4
- require 'seeing_is_believing/example_use'
5
4
 
6
- status = 0
5
+ require 'open3'
6
+ require 'seeing_is_believing/binary'
7
7
 
8
- ARGV.each do |filename|
9
- believer = SeeingIsBelieving::ExampleUse.new File.read(filename), filename
10
- $stdout.puts believer.call
11
- if believer.has_exception?
12
- $stderr.puts believer.exception.message
13
- status = 1
14
- end
15
- end
16
-
17
- exit status
8
+ exit SeeingIsBelieving::Binary.new(ARGV, $stdin, $stdout, $stderr).exitstatus
@@ -0,0 +1,44 @@
1
+ Feature: Running the binary unsuccessfully
2
+
3
+ Sometimes I mess up and use the program in a way that doesn't work.
4
+ I'd like it to be helpful in these situations so I can fix my use.
5
+
6
+ Scenario: Raising exceptions
7
+ Given the file "raises_exception.rb":
8
+ """
9
+ raise "ZOMG!"
10
+ """
11
+ And the file "requires_exception_raising_code.rb":
12
+ """
13
+ 1 + 1
14
+ require_relative 'raises_exception'
15
+ 1 + 1
16
+ """
17
+ When I run "seeing_is_believing requires_exception_raising_code.rb"
18
+ Then stderr is "ZOMG!"
19
+ And the exit status is 1
20
+ And stdout is:
21
+ """
22
+ 1 + 1 # => 2
23
+ require_relative 'raises_exception' # ~> RuntimeError: ZOMG!
24
+ 1 + 1
25
+ """
26
+
27
+ Scenario: Syntactically invalid file
28
+ Given the file "invalid_syntax.rb":
29
+ """
30
+ 'abc
31
+ """
32
+ When I run "seeing_is_believing invalid_syntax.rb"
33
+ Then stderr is:
34
+ """
35
+ invalid_syntax.rb:1: unterminated string meets end of file
36
+ """
37
+ And the exit status is 1
38
+ And stdout is empty
39
+
40
+ Scenario: Passing a nonexistent file
41
+ When I run "seeing_is_believing this_file_does_not_exist.rb"
42
+ Then stderr is "this_file_does_not_exist.rb does not exist!"
43
+ And the exit status is 1
44
+ And stdout is empty
@@ -1,4 +1,5 @@
1
- Feature: Running the binary
1
+ Feature: Running the binary successfully
2
+
2
3
  They say seeing is believing. So to believe that this works
3
4
  I want to see that it works by making a binary to use the lib.
4
5
 
@@ -48,23 +49,6 @@ Feature: Running the binary
48
49
  c" # => "a\n b\n c"
49
50
  """
50
51
 
51
- Scenario: Raising exceptions
52
- Given the file "raises_exception.rb":
53
- """
54
- 1 + 1
55
- raise "ZOMG!"
56
- 1 + 1
57
- """
58
- When I run "seeing_is_believing raises_exception.rb"
59
- Then stderr is "ZOMG!"
60
- And the exit status is 1
61
- And stdout is:
62
- """
63
- 1 + 1 # => 2
64
- raise "ZOMG!" # ~> RuntimeError: ZOMG!
65
- 1 + 1
66
- """
67
-
68
52
  Scenario: Passing previous output back into input
69
53
  Given the file "previous_output.rb":
70
54
  """
@@ -145,8 +129,47 @@ Feature: Running the binary
145
129
  2
146
130
  """
147
131
 
132
+ @not-implemented
133
+ Scenario: Doesn't record BEGIN/END since that's apparently a syntax error
134
+ Given the file "BEGIN_and_END.rb":
135
+ """
136
+ puts 1
137
+ BEGIN {
138
+ puts "begin code"
139
+ some_var = 2
140
+ }
141
+ puts 3
142
+ END {
143
+ puts "end code"
144
+ puts some_var
145
+ }
146
+ puts 4
147
+ """
148
+ When I run "seeing_is_believing BEGIN_and_END.rb"
149
+ Then stderr is empty
150
+ And the exit status is 0
151
+ And stdout is:
152
+ """
153
+ puts 1 # => nil
154
+ BEGIN {
155
+ puts "begin code" # => nil
156
+ some_var = 2 # => 2
157
+ }
158
+ puts 3 # => nil
159
+ END {
160
+ puts "end code" # => nil
161
+ puts some_var # => nil
162
+ }
163
+ puts 4 # => nil
164
+
165
+ # >> begin code
166
+ # >> 1
167
+ # >> 3
168
+ # >> 4
169
+ # >> end code
170
+ # >> 2
171
+ """
172
+
148
173
  Scenario: Requiring other files
149
- Scenario: Syntactically invalid file
150
- Scenario: Passing a nonexistent file
151
174
  Scenario: Evaluating a file that requires other files, from a different directory
152
175
  Scenario: Passing the file on stdin
@@ -0,0 +1,52 @@
1
+ require 'seeing_is_believing/print_results_next_to_lines'
2
+
3
+ class SeeingIsBelieving
4
+ class Binary
5
+ attr_accessor :argv, :stdin, :stdout, :stderr
6
+
7
+ def initialize(argv, stdin, stdout, stderr)
8
+ self.argv = argv
9
+ self.stdin = stdin
10
+ self.stdout = stdout
11
+ self.stderr = stderr
12
+ end
13
+
14
+ def call
15
+ return if @already_called
16
+ @already_called = true
17
+
18
+ unless File.exist? filename
19
+ @exitstatus = 1
20
+ stderr.puts "#{filename} does not exist!"
21
+ return
22
+ end
23
+
24
+ out, err, syntax_status = Open3.capture3('ruby', '-c', filename)
25
+ unless syntax_status.success?
26
+ @exitstatus = 1
27
+ stderr.puts err
28
+ return
29
+ end
30
+
31
+ believer = SeeingIsBelieving::PrintResultsNextToLines.new File.read(filename), filename
32
+ stdout.puts believer.call
33
+ if believer.has_exception?
34
+ stderr.puts believer.exception.message
35
+ @exitstatus = 1
36
+ else
37
+ @exitstatus = 0
38
+ end
39
+ end
40
+
41
+ def exitstatus
42
+ call
43
+ @exitstatus
44
+ end
45
+
46
+ private
47
+
48
+ def filename
49
+ argv.first
50
+ end
51
+ end
52
+ end
@@ -11,7 +11,6 @@
11
11
  # I did look at Ripper, and it will invoke on_kw("__FILE__")
12
12
  # when it sees this.
13
13
 
14
- require 'yaml'
15
14
  require 'open3'
16
15
  require 'fileutils'
17
16
  require 'seeing_is_believing/error'
@@ -99,7 +98,7 @@ class SeeingIsBelieving
99
98
  end
100
99
 
101
100
  def deserialize_result
102
- YAML.load stdout
101
+ Marshal.load stdout
103
102
  end
104
103
 
105
104
  def record_error
@@ -42,6 +42,7 @@ class SeeingIsBelieving
42
42
  def generate
43
43
  @line_number += 1
44
44
  expression = generator.call
45
+ raise SyntaxError unless expression
45
46
  PendingExpression.new(expression, [])
46
47
  end
47
48
 
@@ -2,7 +2,7 @@ require 'seeing_is_believing'
2
2
  require 'seeing_is_believing/has_exception'
3
3
 
4
4
  class SeeingIsBelieving
5
- class ExampleUse
5
+ class PrintResultsNextToLines
6
6
  include HasException
7
7
 
8
8
  STDOUT_PREFIX = '# >>'
@@ -1,10 +1,29 @@
1
+ require 'forwardable'
1
2
  require 'seeing_is_believing/has_exception'
2
3
  require 'seeing_is_believing/tracks_line_numbers_seen'
3
4
 
4
5
  class SeeingIsBelieving
5
6
  class Result
6
7
 
7
- Line = Class.new(Array) { include HasException }
8
+ class Line
9
+ include HasException
10
+
11
+ extend Forwardable
12
+ def_delegators :@array, :[], :<<, :any?, :join, :to_ary, :to_a
13
+
14
+ def initialize
15
+ @array ||= []
16
+ end
17
+
18
+ def ==(ary_or_line)
19
+ if Array === ary_or_line
20
+ @array == ary_or_line
21
+ else
22
+ @array == ary_or_line &&
23
+ has_exception? == ary_or_line.has_exception?
24
+ end
25
+ end
26
+ end
8
27
 
9
28
  include HasException
10
29
  include TracksLineNumbersSeen
@@ -42,7 +61,7 @@ class SeeingIsBelieving
42
61
  # probably not really useful, just exists to satisfy the tests, which specified too simple of an interface
43
62
  def to_a
44
63
  (min_line_number..max_line_number).map do |line_number|
45
- [line_number, [*self[line_number], *Array(self[line_number].exception)]]
64
+ [line_number, [*self[line_number].to_ary, *Array(self[line_number].exception)]]
46
65
  end
47
66
  end
48
67
 
@@ -7,7 +7,6 @@ real_stderr = STDERR
7
7
  STDOUT = $stdout = fake_stdout = StringIO.new
8
8
  STDERR = $stderr = fake_stderr = StringIO.new
9
9
 
10
- require 'yaml'
11
10
  require 'seeing_is_believing/result'
12
11
  $seeing_is_believing_current_result = SeeingIsBelieving::Result.new
13
12
 
@@ -15,5 +14,5 @@ at_exit do
15
14
  $seeing_is_believing_current_result.stdout = fake_stdout.string
16
15
  $seeing_is_believing_current_result.stderr = fake_stderr.string
17
16
 
18
- real_stdout.write YAML.dump $seeing_is_believing_current_result
17
+ real_stdout.write Marshal.dump $seeing_is_believing_current_result
19
18
  end
@@ -1,3 +1,3 @@
1
1
  class SeeingIsBelieving
2
- VERSION = '0.0.4'
2
+ VERSION = '0.0.5'
3
3
  end
@@ -57,7 +57,7 @@ class SeeingIsBelieving
57
57
  "begin;"\
58
58
  "#{code}\n"\
59
59
  "rescue Exception;"\
60
- "line_number = $!.backtrace.first[/:\\d+:/][1..-2].to_i;"\
60
+ "line_number = $!.backtrace.grep(/\#{__FILE__}/).first[/:\\d+:/][1..-2].to_i;"\
61
61
  "$seeing_is_believing_current_result.record_exception line_number, $!;"\
62
62
  "end"
63
63
  end
@@ -131,4 +131,15 @@ describe SeeingIsBelieving::ExpressionList do
131
131
  stream.string.should include "GENERATED"
132
132
  stream.string.should include "REDUCED"
133
133
  end
134
+
135
+ # in reality, the problem may just lie with our lib
136
+ # but it should be correct in most cases
137
+ it 'Raises a syntax error if it cannot generate the expression' do
138
+ generations = ["'"]
139
+ expect do
140
+ described_class.new(
141
+ on_complete: -> { "" }, generator: -> { generations.shift }
142
+ ).call
143
+ end.to raise_error SyntaxError
144
+ end
134
145
  end
@@ -125,10 +125,11 @@ describe SeeingIsBelieving do
125
125
 
126
126
  result[3].should == []
127
127
  result.to_a.size.should == 3
128
+ end
128
129
 
129
- pending 'Not sure how to force the backtrace to render' do
130
- result.exception.backtrace.should be_a_kind_of Array
131
- end
130
+ it 'records the backtrace on the errors' do
131
+ result = invoke("12\nraise Exception, 'omg!'\n12")
132
+ result.exception.backtrace.should be_a_kind_of Array
132
133
  end
133
134
 
134
135
  it 'does not fuck up __LINE__ macro' do
@@ -149,9 +150,8 @@ describe SeeingIsBelieving do
149
150
  values_for("def meth \n return 1 if true \n end \n meth").should == [[], [], ['nil'], ['1']]
150
151
  values_for("def meth \n return 1 if false \n end \n meth").should == [[], [], ['nil'], ['nil']]
151
152
  values_for("-> { \n return 1 \n }.call" ).should == [[], [], ['1']]
152
- pending "this doesn't work because the return detecting code is a very conservative regexp" do
153
- values_for("-> { return 1 }.call" ).should == [['1']]
154
- end
153
+ # this doesn't work because the return detecting code is a very conservative regexp
154
+ # values_for("-> { return 1 }.call" ).should == [['1']]
155
155
  end
156
156
 
157
157
  it 'does not affect its environment' do
@@ -201,6 +201,7 @@ describe SeeingIsBelieving do
201
201
  values_for("1+1\nDATA.read\n__END__\n....").should == [['2'], ['"...."']]
202
202
  end
203
203
 
204
- # something about when the whole input is invalid
205
- # something about multi-line strings
204
+ it 'raises a SyntaxError when the whole program is invalid' do
205
+ expect { invoke '"' }.to raise_error SyntaxError
206
+ end
206
207
  end
@@ -121,10 +121,12 @@ describe SeeingIsBelieving::SyntaxAnalyzer do
121
121
  will_return["o.return"].should be_false
122
122
  will_return[":return"].should be_false
123
123
  will_return["'return'"].should be_false
124
- # will_return["'return\nreturn\nreturn'"].should be_false
125
124
  will_return["def a\nreturn 1\nend"].should be_false
126
125
  will_return["-> {\nreturn 1\n}"].should be_false
127
126
  will_return["Proc.new {\nreturn 1\n}"].should be_false
128
- # will_return["return \\\n1"].should be_true
127
+ pending "this doesn't work because the return detecting code is an insufficient regexp" do
128
+ will_return["'return\nreturn\nreturn'"].should be_false
129
+ will_return["return \\\n1"].should be_true
130
+ end
129
131
  end
130
132
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: seeing_is_believing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-28 00:00:00.000000000 Z
12
+ date: 2013-01-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70133565808080 !ruby/object:Gem::Requirement
16
+ requirement: &70333793492220 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 2.12.0
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70133565808080
24
+ version_requirements: *70333793492220
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: cucumber
27
- requirement: &70133565807280 !ruby/object:Gem::Requirement
27
+ requirement: &70333793491440 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 1.2.1
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70133565807280
35
+ version_requirements: *70333793491440
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: ichannel
38
- requirement: &70133565806600 !ruby/object:Gem::Requirement
38
+ requirement: &70333793490760 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: 5.1.1
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70133565806600
46
+ version_requirements: *70333793490760
47
47
  description: Records the results of every line of code in your file (intended to be
48
48
  like xmpfilter), inspired by Bret Victor's JavaScript example in his talk "Inventing
49
49
  on Principle"
@@ -57,18 +57,21 @@ files:
57
57
  - .gitignore
58
58
  - Gemfile
59
59
  - Gemfile.lock
60
+ - Rakefile
60
61
  - Readme.md
61
62
  - bin/seeing_is_believing
62
- - features/binary.feature
63
+ - features/binary_errors.feature
64
+ - features/binary_examples.feature
63
65
  - features/step_definitions/steps.rb
64
66
  - features/support/env.rb
65
67
  - lib/seeing_is_believing.rb
68
+ - lib/seeing_is_believing/binary.rb
66
69
  - lib/seeing_is_believing/error.rb
67
70
  - lib/seeing_is_believing/evaluate_by_moving_files.rb
68
- - lib/seeing_is_believing/example_use.rb
69
71
  - lib/seeing_is_believing/expression_list.rb
70
72
  - lib/seeing_is_believing/hard_core_ensure.rb
71
73
  - lib/seeing_is_believing/has_exception.rb
74
+ - lib/seeing_is_believing/print_results_next_to_lines.rb
72
75
  - lib/seeing_is_believing/result.rb
73
76
  - lib/seeing_is_believing/syntax_analyzer.rb
74
77
  - lib/seeing_is_believing/the_matrix.rb
@@ -105,7 +108,8 @@ signing_key:
105
108
  specification_version: 3
106
109
  summary: Records results of every line of code in your file
107
110
  test_files:
108
- - features/binary.feature
111
+ - features/binary_errors.feature
112
+ - features/binary_examples.feature
109
113
  - features/step_definitions/steps.rb
110
114
  - features/support/env.rb
111
115
  - spec/evaluate_by_moving_files_spec.rb