seeing_is_believing 0.0.7 → 0.0.8
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 +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"
|