seeing_is_believing 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/Readme.md +11 -11
- data/features/binary_examples.feature +13 -7
- data/lib/seeing_is_believing.rb +4 -3
- data/lib/seeing_is_believing/expression_list.rb +17 -8
- data/lib/seeing_is_believing/version.rb +1 -1
- data/spec/expression_list_spec.rb +30 -3
- data/spec/seeing_is_believing_spec.rb +5 -0
- metadata +9 -9
data/Readme.md
CHANGED
@@ -64,15 +64,6 @@ result[2] # => ['"A"', '"B"', '"C"']
|
|
64
64
|
Install
|
65
65
|
=======
|
66
66
|
|
67
|
-
For now, since Rubygems is not allowing pushes:
|
68
|
-
|
69
|
-
$ git clone https://github.com/JoshCheek/seeing_is_believing/
|
70
|
-
$ cd seeing_is_believing
|
71
|
-
$ gem build seeing_is_believing.gemspec
|
72
|
-
$ gem install seeing_is_believing-0.0.7.gem
|
73
|
-
$ cd ..
|
74
|
-
$ rm -rf "./seeing_is_believing"
|
75
|
-
|
76
67
|
When Rubygems gets back up:
|
77
68
|
|
78
69
|
$ gem install seeing_is_believing
|
@@ -81,6 +72,15 @@ Or if you haven't fixed your gem home, and you aren't using any version managers
|
|
81
72
|
|
82
73
|
$ sudo gem install seeing_is_believing
|
83
74
|
|
75
|
+
Rubygems is allowing pushes again, but if it goes back down, you can install like this:
|
76
|
+
|
77
|
+
$ git clone https://github.com/JoshCheek/seeing_is_believing/
|
78
|
+
$ cd seeing_is_believing
|
79
|
+
$ gem build seeing_is_believing.gemspec
|
80
|
+
$ gem install seeing_is_believing-0.0.8.gem
|
81
|
+
$ cd ..
|
82
|
+
$ rm -rf "./seeing_is_believing"
|
83
|
+
|
84
84
|
Hook it into TextMate
|
85
85
|
=====================
|
86
86
|
|
@@ -97,9 +97,9 @@ It should look like this:
|
|
97
97
|
Known Issues
|
98
98
|
============
|
99
99
|
|
100
|
-
*
|
101
|
-
* `BEGIN/END` breaks things and I probably won't take the time to fix it, becuase it's nontrivial, but there is currently a cuke for it
|
100
|
+
* `BEGIN/END` breaks things and I probably won't take the time to fix it, becuase it's nontrivial and its really meant for command-line scripts, but there is currently a cuke for it
|
102
101
|
* Heredocs aren't recorded. It might actually be possible if the ExpressionList were to get smarter
|
102
|
+
* Return statements are dealt with poorly, causing some situations where you could capture and display a value to not capture
|
103
103
|
|
104
104
|
License
|
105
105
|
=======
|
@@ -35,6 +35,9 @@ Feature: Running the binary successfully
|
|
35
35
|
<<HERE
|
36
36
|
is a doc
|
37
37
|
HERE
|
38
|
+
|
39
|
+
[*1..10]
|
40
|
+
.select(&:even?)
|
38
41
|
"""
|
39
42
|
When I run "seeing_is_believing basic_functionality.rb"
|
40
43
|
Then stderr is empty
|
@@ -42,16 +45,16 @@ Feature: Running the binary successfully
|
|
42
45
|
And stdout is:
|
43
46
|
"""
|
44
47
|
5.times do |i|
|
45
|
-
i * 2
|
46
|
-
end
|
48
|
+
i * 2 # => 0, 2, 4, 6, 8
|
49
|
+
end # => 5
|
47
50
|
|
48
51
|
def meth(n)
|
49
|
-
n
|
50
|
-
end
|
52
|
+
n # => "12", "34"
|
53
|
+
end # => nil
|
51
54
|
|
52
55
|
# some invocations
|
53
|
-
meth "12"
|
54
|
-
meth "34"
|
56
|
+
meth "12" # => "12"
|
57
|
+
meth "34" # => "34"
|
55
58
|
|
56
59
|
=begin
|
57
60
|
I don't ever actually write
|
@@ -61,12 +64,15 @@ Feature: Running the binary successfully
|
|
61
64
|
# multilinezzz
|
62
65
|
"a
|
63
66
|
b
|
64
|
-
c"
|
67
|
+
c" # => "a\n b\n c"
|
65
68
|
|
66
69
|
# don't record heredocs b/c they're just too fucking different
|
67
70
|
<<HERE
|
68
71
|
is a doc
|
69
72
|
HERE
|
73
|
+
|
74
|
+
[*1..10]
|
75
|
+
.select(&:even?) # => [2, 4, 6, 8, 10]
|
70
76
|
"""
|
71
77
|
|
72
78
|
Scenario: Passing previous output back into input
|
data/lib/seeing_is_believing.rb
CHANGED
@@ -20,7 +20,7 @@ class SeeingIsBelieving
|
|
20
20
|
def call
|
21
21
|
@memoized_result ||= begin
|
22
22
|
program = ''
|
23
|
-
program << expression_list.call until
|
23
|
+
program << expression_list.call until peek_next_line.nil? || data_segment?
|
24
24
|
program = record_exceptions_in program
|
25
25
|
program << "\n" << the_rest_of_the_stream if data_segment?
|
26
26
|
result_for program, min_line_number, max_line_number
|
@@ -32,8 +32,9 @@ class SeeingIsBelieving
|
|
32
32
|
attr_reader :stream
|
33
33
|
|
34
34
|
def expression_list
|
35
|
-
@expression_list ||= ExpressionList.new
|
36
|
-
|
35
|
+
@expression_list ||= ExpressionList.new get_next_line: lambda { get_next_line },
|
36
|
+
peek_next_line: lambda { peek_next_line },
|
37
|
+
on_complete: lambda { |line, children, completions, line_number|
|
37
38
|
track_line_number line_number
|
38
39
|
expression = [line, *children, *completions].map(&:chomp).join("\n")
|
39
40
|
if do_not_record? expression
|
@@ -16,11 +16,12 @@ class SeeingIsBelieving
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def initialize(options)
|
19
|
-
self.debug_stream
|
20
|
-
self.should_debug
|
21
|
-
self.
|
22
|
-
self.
|
23
|
-
|
19
|
+
self.debug_stream = options.fetch :debug_stream, $stdout
|
20
|
+
self.should_debug = options.fetch :debug, false
|
21
|
+
self.get_next_line = options.fetch :get_next_line
|
22
|
+
self.peek_next_line = options.fetch :peek_next_line
|
23
|
+
self.on_complete = options.fetch :on_complete
|
24
|
+
@line_number = 0
|
24
25
|
end
|
25
26
|
|
26
27
|
def call
|
@@ -30,22 +31,30 @@ class SeeingIsBelieving
|
|
30
31
|
pending_expression = generate
|
31
32
|
debug { "GENERATED: #{pending_expression.expression.inspect}, ADDING IT TO #{inspected_expressions expressions}" }
|
32
33
|
expressions << pending_expression
|
33
|
-
expression = reduce expressions
|
34
|
+
expression = reduce expressions unless next_line_modifies_current?
|
34
35
|
end until expressions.empty?
|
35
36
|
expression
|
36
37
|
end
|
37
38
|
|
38
39
|
private
|
39
40
|
|
40
|
-
attr_accessor :debug_stream, :should_debug, :
|
41
|
+
attr_accessor :debug_stream, :should_debug, :get_next_line, :peek_next_line, :on_complete, :expressions
|
41
42
|
|
42
43
|
def generate
|
43
44
|
@line_number += 1
|
44
|
-
expression =
|
45
|
+
expression = get_next_line.call
|
45
46
|
raise SyntaxError unless expression
|
46
47
|
PendingExpression.new(expression, [])
|
47
48
|
end
|
48
49
|
|
50
|
+
def next_line_modifies_current?
|
51
|
+
# method invocations can be put on the next line, and begin with a dot.
|
52
|
+
# I think that's the only case we need to worry about. e.g:
|
53
|
+
# 3
|
54
|
+
# .times { |i| p i }
|
55
|
+
peek_next_line.call && peek_next_line.call =~ /^\s*\./
|
56
|
+
end
|
57
|
+
|
49
58
|
def inspected_expressions(expressions)
|
50
59
|
"[#{expressions.map { |pe| pe.inspect debug? }.join(', ')}]"
|
51
60
|
end
|
@@ -2,9 +2,16 @@ require 'seeing_is_believing/expression_list'
|
|
2
2
|
|
3
3
|
describe SeeingIsBelieving::ExpressionList do
|
4
4
|
|
5
|
+
def list_for(generations, options={}, &block)
|
6
|
+
described_class.new({
|
7
|
+
on_complete: block,
|
8
|
+
get_next_line: -> { generations.shift || raise("EMPTY!") },
|
9
|
+
peek_next_line: -> { generations.first },
|
10
|
+
}.merge(options))
|
11
|
+
end
|
12
|
+
|
5
13
|
def call(generations, options={}, &block)
|
6
|
-
options
|
7
|
-
described_class.new(options).call
|
14
|
+
list_for(generations, options, &block).call
|
8
15
|
end
|
9
16
|
|
10
17
|
example 'example: multiple children' do
|
@@ -146,6 +153,24 @@ describe SeeingIsBelieving::ExpressionList do
|
|
146
153
|
end
|
147
154
|
end
|
148
155
|
|
156
|
+
example "example: method invocations on next line" do
|
157
|
+
# example 1: consume the expression with lines after
|
158
|
+
list = list_for ['a', '.b', ' .c', 'irrelevant'] do |*expressions, line_number|
|
159
|
+
line_number.should == 3
|
160
|
+
expressions.flatten.join('').should == 'a.b .c'
|
161
|
+
'a.b.c'
|
162
|
+
end
|
163
|
+
list.call.should == 'a.b.c'
|
164
|
+
|
165
|
+
# example 2: consume the expression with no lines after
|
166
|
+
list = list_for ['a', '.b'] do |*expressions, line_number|
|
167
|
+
line_number.should == 2
|
168
|
+
expressions.flatten.join('').should == 'a.b'
|
169
|
+
'result'
|
170
|
+
end
|
171
|
+
list.call.should == 'result'
|
172
|
+
end
|
173
|
+
|
149
174
|
example "example: smoke test debug option" do
|
150
175
|
stream = StringIO.new
|
151
176
|
call(%w[a+ b], debug: true, debug_stream: stream) { |*expressions, _| expressions.join("\n") }
|
@@ -159,7 +184,9 @@ describe SeeingIsBelieving::ExpressionList do
|
|
159
184
|
generations = ["'"]
|
160
185
|
expect do
|
161
186
|
described_class.new(
|
162
|
-
on_complete:
|
187
|
+
on_complete: -> { "" },
|
188
|
+
get_next_line: -> { generations.shift },
|
189
|
+
peek_next_line: -> { generations.first }
|
163
190
|
).call
|
164
191
|
end.to raise_error SyntaxError
|
165
192
|
end
|
@@ -226,4 +226,9 @@ describe SeeingIsBelieving do
|
|
226
226
|
it 'defaults the stdin stream to an empty string' do
|
227
227
|
invoke('$stdin.read')[1].should == ['""']
|
228
228
|
end
|
229
|
+
|
230
|
+
it 'can deal with methods that are invoked entirely on the next line', wip:true do
|
231
|
+
values_for("1\n.even?").should == [[], ['false']]
|
232
|
+
values_for("1\n.even?\n__END__").should == [[], ['false']]
|
233
|
+
end
|
229
234
|
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
|
+
version: 0.0.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2013-02-02 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement: &
|
16
|
+
requirement: &70138255056540 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 10.0.3
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70138255056540
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &70138255055760 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 2.12.0
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70138255055760
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: cucumber
|
38
|
-
requirement: &
|
38
|
+
requirement: &70138255055080 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 1.2.1
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70138255055080
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: ichannel
|
49
|
-
requirement: &
|
49
|
+
requirement: &70138255054620 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: 5.1.1
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70138255054620
|
58
58
|
description: Records the results of every line of code in your file (intended to be
|
59
59
|
like xmpfilter), inspired by Bret Victor's JavaScript example in his talk "Inventing
|
60
60
|
on Principle"
|