seeing_is_believing 0.0.9 → 0.0.10
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/Gemfile.lock +1 -1
- data/Readme.md +5 -3
- data/features/examples.feature +45 -11
- data/features/flags.feature +70 -0
- data/lib/seeing_is_believing/binary/arg_parser.rb +92 -0
- data/lib/seeing_is_believing/binary/line_formatter.rb +47 -0
- data/lib/seeing_is_believing/binary/print_results_next_to_lines.rb +127 -0
- data/lib/seeing_is_believing/binary.rb +24 -25
- data/lib/seeing_is_believing/evaluate_by_moving_files.rb +9 -10
- data/lib/seeing_is_believing/expression_list.rb +8 -11
- data/lib/seeing_is_believing/version.rb +1 -1
- data/lib/seeing_is_believing.rb +42 -15
- data/spec/arg_parser_spec.rb +44 -24
- data/spec/evaluate_by_moving_files_spec.rb +0 -7
- data/spec/expression_list_spec.rb +35 -31
- data/spec/line_formatter_spec.rb +53 -0
- data/spec/seeing_is_believing_spec.rb +10 -5
- metadata +15 -12
- data/lib/seeing_is_believing/arg_parser.rb +0 -94
- data/lib/seeing_is_believing/print_results_next_to_lines.rb +0 -117
@@ -1,5 +1,7 @@
|
|
1
|
-
require 'seeing_is_believing
|
2
|
-
require 'seeing_is_believing/
|
1
|
+
require 'seeing_is_believing'
|
2
|
+
require 'seeing_is_believing/binary/arg_parser'
|
3
|
+
require 'seeing_is_believing/binary/print_results_next_to_lines'
|
4
|
+
|
3
5
|
|
4
6
|
class SeeingIsBelieving
|
5
7
|
class Binary
|
@@ -17,7 +19,7 @@ class SeeingIsBelieving
|
|
17
19
|
elsif should_print_help? then print_help ; 0
|
18
20
|
elsif has_filename? && file_dne? then print_file_dne ; 1
|
19
21
|
elsif invalid_syntax? then print_syntax_error ; 1
|
20
|
-
else print_program ; (
|
22
|
+
else print_program ; (results.has_exception? ? 1 : 0)
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
@@ -25,27 +27,23 @@ class SeeingIsBelieving
|
|
25
27
|
|
26
28
|
private
|
27
29
|
|
28
|
-
def
|
30
|
+
def has_filename?
|
29
31
|
flags[:filename]
|
30
32
|
end
|
31
|
-
alias has_filename? filename
|
32
33
|
|
33
|
-
|
34
|
+
def body
|
35
|
+
@body ||= PrintResultsNextToLines.remove_previous_output_from \
|
36
|
+
(file_is_on_stdin? ? stdin.read : File.read(flags[:filename]))
|
37
|
+
end
|
38
|
+
|
39
|
+
def results
|
40
|
+
@results ||= SeeingIsBelieving.call body,
|
41
|
+
filename: flags[:filename],
|
42
|
+
stdin: (file_is_on_stdin? ? '' : stdin)
|
43
|
+
end
|
44
|
+
|
34
45
|
def printer
|
35
|
-
@printer ||=
|
36
|
-
if file_is_on_stdin?
|
37
|
-
body = stdin.read
|
38
|
-
stdin = ''
|
39
|
-
else
|
40
|
-
body = File.read(filename)
|
41
|
-
stdin = self.stdin
|
42
|
-
end
|
43
|
-
PrintResultsNextToLines.new body,
|
44
|
-
stdin,
|
45
|
-
filename: filename,
|
46
|
-
start_line: flags[:start_line],
|
47
|
-
end_line: flags[:end_line]
|
48
|
-
end
|
46
|
+
@printer ||= PrintResultsNextToLines.new body, results, flags
|
49
47
|
end
|
50
48
|
|
51
49
|
def flags
|
@@ -69,15 +67,15 @@ class SeeingIsBelieving
|
|
69
67
|
end
|
70
68
|
|
71
69
|
def file_is_on_stdin?
|
72
|
-
filename.nil?
|
70
|
+
flags[:filename].nil?
|
73
71
|
end
|
74
72
|
|
75
73
|
def file_dne?
|
76
|
-
!File.exist?(filename)
|
74
|
+
!File.exist?(flags[:filename])
|
77
75
|
end
|
78
76
|
|
79
77
|
def print_file_dne
|
80
|
-
stderr.puts "#{filename} does not exist!"
|
78
|
+
stderr.puts "#{flags[:filename]} does not exist!"
|
81
79
|
end
|
82
80
|
|
83
81
|
def print_program
|
@@ -85,8 +83,8 @@ class SeeingIsBelieving
|
|
85
83
|
end
|
86
84
|
|
87
85
|
def syntax_error_notice
|
88
|
-
return if file_is_on_stdin? # <-- should
|
89
|
-
out, err, syntax_status = Open3.capture3
|
86
|
+
return if file_is_on_stdin? # <-- BUG: should check stdin too
|
87
|
+
out, err, syntax_status = Open3.capture3 'ruby', '-c', flags[:filename]
|
90
88
|
return err unless syntax_status.success?
|
91
89
|
end
|
92
90
|
|
@@ -97,5 +95,6 @@ class SeeingIsBelieving
|
|
97
95
|
def print_syntax_error
|
98
96
|
stderr.puts syntax_error_notice
|
99
97
|
end
|
98
|
+
|
100
99
|
end
|
101
100
|
end
|
@@ -20,17 +20,18 @@ require 'seeing_is_believing/hard_core_ensure'
|
|
20
20
|
|
21
21
|
class SeeingIsBelieving
|
22
22
|
class EvaluateByMovingFiles
|
23
|
-
attr_accessor :program, :filename, :error_stream, :input_stream
|
23
|
+
attr_accessor :program, :filename, :error_stream, :input_stream, :matrix_filename
|
24
24
|
|
25
25
|
def initialize(program, filename, options={})
|
26
|
-
self.program
|
27
|
-
self.filename
|
28
|
-
self.error_stream
|
29
|
-
self.input_stream
|
26
|
+
self.program = program
|
27
|
+
self.filename = filename
|
28
|
+
self.error_stream = options.fetch :error_stream, $stderr # hmm, not really liking the global here
|
29
|
+
self.input_stream = options.fetch :input_stream, StringIO.new('')
|
30
|
+
self.matrix_filename = options[:matrix_filename] || 'seeing_is_believing/the_matrix'
|
30
31
|
end
|
31
32
|
|
32
33
|
def call
|
33
|
-
@result ||= HardCoreEnsure.call
|
34
|
+
@result ||= HardCoreEnsure.call \
|
34
35
|
code: -> {
|
35
36
|
dont_overwrite_existing_tempfile!
|
36
37
|
move_file_to_tempfile
|
@@ -47,7 +48,6 @@ class SeeingIsBelieving
|
|
47
48
|
ensure: -> {
|
48
49
|
restore_backup
|
49
50
|
}
|
50
|
-
)
|
51
51
|
end
|
52
52
|
|
53
53
|
def file_directory
|
@@ -83,9 +83,8 @@ class SeeingIsBelieving
|
|
83
83
|
|
84
84
|
def evaluate_file
|
85
85
|
Open3.popen3 'ruby', '-W0', # no warnings (b/c I hijack STDOUT/STDERR)
|
86
|
-
'-I', File.expand_path('../..', __FILE__), #
|
87
|
-
'-r',
|
88
|
-
'-C', file_directory, # run in the file's directory
|
86
|
+
'-I', File.expand_path('../..', __FILE__), # add lib to the load path
|
87
|
+
'-r', matrix_filename, # hijack the environment so it can be recorded
|
89
88
|
filename do |i, o, e, t|
|
90
89
|
out_reader = Thread.new { o.read }
|
91
90
|
err_reader = Thread.new { e.read }
|
@@ -21,19 +21,18 @@ class SeeingIsBelieving
|
|
21
21
|
self.get_next_line = options.fetch :get_next_line
|
22
22
|
self.peek_next_line = options.fetch :peek_next_line
|
23
23
|
self.on_complete = options.fetch :on_complete
|
24
|
-
@line_number = 0
|
25
24
|
end
|
26
25
|
|
27
26
|
def call
|
28
|
-
expressions = []
|
29
|
-
expression = nil
|
27
|
+
offset, expressions, expression = 0, [], nil
|
30
28
|
begin
|
31
29
|
pending_expression = generate
|
32
30
|
debug { "GENERATED: #{pending_expression.expression.inspect}, ADDING IT TO #{inspected_expressions expressions}" }
|
33
31
|
expressions << pending_expression
|
34
|
-
expression = reduce expressions unless next_line_modifies_current?
|
32
|
+
expression = reduce expressions, offset unless next_line_modifies_current?
|
33
|
+
offset += 1
|
35
34
|
end until expressions.empty?
|
36
|
-
expression
|
35
|
+
return expression, offset
|
37
36
|
end
|
38
37
|
|
39
38
|
private
|
@@ -41,7 +40,6 @@ class SeeingIsBelieving
|
|
41
40
|
attr_accessor :debug_stream, :should_debug, :get_next_line, :peek_next_line, :on_complete, :expressions
|
42
41
|
|
43
42
|
def generate
|
44
|
-
@line_number += 1
|
45
43
|
expression = get_next_line.call
|
46
44
|
raise SyntaxError unless expression
|
47
45
|
PendingExpression.new(expression, [])
|
@@ -49,9 +47,8 @@ class SeeingIsBelieving
|
|
49
47
|
|
50
48
|
def next_line_modifies_current?
|
51
49
|
# 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.
|
53
|
-
# 3
|
54
|
-
# .times { |i| p i }
|
50
|
+
# I think that's the only case we need to worry about.
|
51
|
+
# e.g: `3\n.times { |i| p i }`
|
55
52
|
peek_next_line.call && peek_next_line.call =~ /^\s*\./
|
56
53
|
end
|
57
54
|
|
@@ -67,7 +64,7 @@ class SeeingIsBelieving
|
|
67
64
|
@debug_stream.puts yield if debug?
|
68
65
|
end
|
69
66
|
|
70
|
-
def reduce(expressions)
|
67
|
+
def reduce(expressions, offset)
|
71
68
|
expressions.size.times do |i|
|
72
69
|
expression = expressions[i..-1].map(&:expression) # uhm, should this expression we are checking for validity consider the children?
|
73
70
|
.join("\n") # must use newline otherwise can get expressions like `a\\+b` that should be `a\\\n+b`, former is invalid
|
@@ -76,7 +73,7 @@ class SeeingIsBelieving
|
|
76
73
|
result = on_complete.call(expressions[i].expression,
|
77
74
|
expressions[i].children,
|
78
75
|
expressions[i+1..-1].map { |pe| [pe.expression, pe.children] }.flatten, # hmmm, not sure this is really correct, but it allows it to work for my use cases
|
79
|
-
|
76
|
+
offset)
|
80
77
|
expressions.replace expressions[0, i]
|
81
78
|
expressions[i-1].children << result unless expressions.empty?
|
82
79
|
debug { "REDUCED: #{result.inspect}, LIST: #{inspected_expressions expressions}" }
|
data/lib/seeing_is_believing.rb
CHANGED
@@ -11,18 +11,49 @@ class SeeingIsBelieving
|
|
11
11
|
include TracksLineNumbersSeen
|
12
12
|
BLANK_REGEX = /\A\s*\Z/
|
13
13
|
|
14
|
+
def self.call(*args)
|
15
|
+
new(*args).call
|
16
|
+
end
|
17
|
+
|
14
18
|
def initialize(string_or_stream, options={})
|
15
|
-
@string
|
16
|
-
@stream
|
17
|
-
@
|
18
|
-
@
|
19
|
+
@string = string_or_stream
|
20
|
+
@stream = to_stream string_or_stream
|
21
|
+
@matrix_filename = options[:matrix_filename]
|
22
|
+
@filename = options[:filename]
|
23
|
+
@stdin = to_stream options.fetch(:stdin, '')
|
24
|
+
@line_number = 1
|
19
25
|
end
|
20
26
|
|
27
|
+
# :( refactor me
|
21
28
|
def call
|
22
29
|
@memoized_result ||= begin
|
30
|
+
# extract leading comments, leading =begin and magic comments can't be wrapped for exceptions without breaking
|
31
|
+
leading_comments = ''
|
32
|
+
while next_line_queue.peek =~ /^\s*#/
|
33
|
+
leading_comments << next_line_queue.dequeue << "\n"
|
34
|
+
@line_number += 1
|
35
|
+
end
|
36
|
+
while next_line_queue.peek == '=begin'
|
37
|
+
lines = next_line_queue.dequeue << "\n"
|
38
|
+
@line_number += 1
|
39
|
+
until SyntaxAnalyzer.begin_and_end_comments_are_complete? lines
|
40
|
+
lines << next_line_queue.dequeue << "\n"
|
41
|
+
@line_number += 1
|
42
|
+
end
|
43
|
+
leading_comments << lines
|
44
|
+
end
|
45
|
+
|
46
|
+
# extract program
|
23
47
|
program = ''
|
24
|
-
|
25
|
-
|
48
|
+
until next_line_queue.peek.nil? || data_segment?
|
49
|
+
expression, expression_size = expression_list.call
|
50
|
+
program << expression
|
51
|
+
track_line_number @line_number
|
52
|
+
@line_number += expression_size
|
53
|
+
end
|
54
|
+
program = leading_comments + record_exceptions_in(program)
|
55
|
+
|
56
|
+
# extract data segment
|
26
57
|
program << "\n" << the_rest_of_the_stream if data_segment?
|
27
58
|
result_for program, min_line_number, max_line_number
|
28
59
|
end
|
@@ -30,18 +61,17 @@ class SeeingIsBelieving
|
|
30
61
|
|
31
62
|
private
|
32
63
|
|
33
|
-
attr_reader :stream
|
64
|
+
attr_reader :stream, :matrix_filename
|
34
65
|
|
35
66
|
def expression_list
|
36
67
|
@expression_list ||= ExpressionList.new get_next_line: lambda { next_line_queue.dequeue },
|
37
68
|
peek_next_line: lambda { next_line_queue.peek },
|
38
|
-
on_complete: lambda { |line, children, completions,
|
39
|
-
track_line_number line_number
|
69
|
+
on_complete: lambda { |line, children, completions, offset|
|
40
70
|
expression = [line, *children, *completions].map(&:chomp).join("\n")
|
41
71
|
if do_not_record? expression
|
42
72
|
expression + "\n"
|
43
73
|
else
|
44
|
-
record_yahself(expression, line_number) + "\n"
|
74
|
+
record_yahself(expression, @line_number+offset) + "\n"
|
45
75
|
end
|
46
76
|
}
|
47
77
|
end
|
@@ -68,7 +98,7 @@ class SeeingIsBelieving
|
|
68
98
|
def result_for(program, min_line_number, max_line_number)
|
69
99
|
Dir.mktmpdir "seeing_is_believing_temp_dir" do |dir|
|
70
100
|
filename = @filename || File.join(dir, 'program.rb')
|
71
|
-
EvaluateByMovingFiles.new(program, filename, input_stream: @stdin).call.tap do |result|
|
101
|
+
EvaluateByMovingFiles.new(program, filename, input_stream: @stdin, matrix_filename: matrix_filename).call.tap do |result|
|
72
102
|
result.track_line_number min_line_number
|
73
103
|
result.track_line_number max_line_number
|
74
104
|
end
|
@@ -84,10 +114,7 @@ class SeeingIsBelieving
|
|
84
114
|
end
|
85
115
|
|
86
116
|
def next_line_queue
|
87
|
-
@next_line_queue ||= Queue.new
|
88
|
-
line = stream.gets
|
89
|
-
line && line.chomp
|
90
|
-
end
|
117
|
+
@next_line_queue ||= Queue.new { (line = stream.gets) && line.chomp }
|
91
118
|
end
|
92
119
|
|
93
120
|
def the_rest_of_the_stream
|
data/spec/arg_parser_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require 'seeing_is_believing/arg_parser'
|
1
|
+
require 'seeing_is_believing/binary/arg_parser'
|
2
2
|
|
3
|
-
describe SeeingIsBelieving::ArgParser do
|
3
|
+
describe SeeingIsBelieving::Binary::ArgParser do
|
4
4
|
RSpec::Matchers.define :have_error do |error_assertion|
|
5
5
|
match do |options|
|
6
6
|
options[:errors].find do |error|
|
@@ -26,6 +26,20 @@ describe SeeingIsBelieving::ArgParser do
|
|
26
26
|
described_class.parse args
|
27
27
|
end
|
28
28
|
|
29
|
+
shared_examples 'it requires a positive int argument' do |flags|
|
30
|
+
it 'expects an integer argument' do
|
31
|
+
flags.each do |flag|
|
32
|
+
parse([flag, '1']).should_not have_error /#{flag}/
|
33
|
+
parse([flag, '0']).should have_error /#{flag}/
|
34
|
+
parse([flag, '-1']).should have_error /#{flag}/
|
35
|
+
parse([flag, '1.0']).should have_error /#{flag}/
|
36
|
+
parse([flag, 'a']).should have_error /#{flag}/
|
37
|
+
parse([flag, '' ]).should have_error /#{flag}/
|
38
|
+
parse([flag ]).should have_error /#{flag}/
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
29
43
|
specify 'unknown options set an error' do
|
30
44
|
parse(['--abc']).should have_error 'Unknown option: "--abc"'
|
31
45
|
parse(['-a']).should have_error 'Unknown option: "-a"'
|
@@ -68,18 +82,7 @@ describe SeeingIsBelieving::ArgParser do
|
|
68
82
|
parse(['--start-line', '12'])[:start_line].should == 12
|
69
83
|
end
|
70
84
|
|
71
|
-
|
72
|
-
line_error_assertions = lambda do |flag|
|
73
|
-
parse([flag, '1']).should_not have_error /#{flag}/
|
74
|
-
parse([flag, '0']).should have_error /#{flag}/
|
75
|
-
parse([flag, 'a']).should have_error /#{flag}/
|
76
|
-
parse([flag, '']).should have_error /#{flag}/
|
77
|
-
parse([flag, '1.0']).should have_error /#{flag}/
|
78
|
-
parse([flag]).should have_error /#{flag}/
|
79
|
-
end
|
80
|
-
line_error_assertions['-l']
|
81
|
-
line_error_assertions['--start-line']
|
82
|
-
end
|
85
|
+
it_behaves_like 'it requires a positive int argument', ['-l', '--start-line']
|
83
86
|
end
|
84
87
|
|
85
88
|
describe ':end_line' do
|
@@ -92,16 +95,7 @@ describe SeeingIsBelieving::ArgParser do
|
|
92
95
|
parse(['--end-line', '12'])[:end_line].should == 12
|
93
96
|
end
|
94
97
|
|
95
|
-
|
96
|
-
line_error_assertions = lambda do |flag|
|
97
|
-
parse([flag, '1']).should_not have_error /#{flag}/
|
98
|
-
parse([flag, 'a']).should have_error /#{flag}/
|
99
|
-
parse([flag, '']).should have_error /#{flag}/
|
100
|
-
parse([flag]).should have_error /#{flag}/
|
101
|
-
end
|
102
|
-
line_error_assertions['-L']
|
103
|
-
line_error_assertions['--end-line']
|
104
|
-
end
|
98
|
+
it_behaves_like 'it requires a positive int argument', ['-L', '--end-line']
|
105
99
|
end
|
106
100
|
|
107
101
|
it 'swaps start and end line around if they are out of order' do
|
@@ -109,6 +103,32 @@ describe SeeingIsBelieving::ArgParser do
|
|
109
103
|
parse(%w[-l 2 -L 1])[:end_line].should == 2
|
110
104
|
end
|
111
105
|
|
106
|
+
describe ':result_length' do
|
107
|
+
it 'defaults to infinity' do
|
108
|
+
parse([])[:result_length].should == Float::INFINITY
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'is set with -D and --result-length' do
|
112
|
+
parse(['-D', '10'])[:result_length].should == 10
|
113
|
+
parse(['--result-length', '10'])[:result_length].should == 10
|
114
|
+
end
|
115
|
+
|
116
|
+
it_behaves_like 'it requires a positive int argument', ['-D', '--result-length']
|
117
|
+
end
|
118
|
+
|
119
|
+
describe ':line_length' do
|
120
|
+
it 'defaults to infinity' do
|
121
|
+
parse([])[:line_length].should == Float::INFINITY
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'is set with -d and --line-length' do
|
125
|
+
parse(['-d', '10'])[:line_length].should == 10
|
126
|
+
parse(['--line-length', '10'])[:line_length].should == 10
|
127
|
+
end
|
128
|
+
|
129
|
+
it_behaves_like 'it requires a positive int argument', ['-d', '--line-length']
|
130
|
+
end
|
131
|
+
|
112
132
|
describe ':help' do
|
113
133
|
it 'defaults to nil' do
|
114
134
|
parse([])[:help].should be_nil
|
@@ -68,11 +68,4 @@ describe SeeingIsBelieving::EvaluateByMovingFiles do
|
|
68
68
|
expect { evaluator.call }.to raise_error
|
69
69
|
stderr.string.should include "It blew up"
|
70
70
|
end
|
71
|
-
|
72
|
-
it "doesn't block waiting for io on stdin" do
|
73
|
-
reader, writer = IO.pipe
|
74
|
-
thread = Thread.new { invoke '1', input_stream: reader }
|
75
|
-
sleep 0.05
|
76
|
-
thread.should_not be_alive
|
77
|
-
end
|
78
71
|
end
|
@@ -16,31 +16,32 @@ describe SeeingIsBelieving::ExpressionList do
|
|
16
16
|
|
17
17
|
example 'example: multiple children' do
|
18
18
|
block_invocations = 0
|
19
|
-
result = call %w[a( b+ c x\\ + y )] do |line, children, completions,
|
20
|
-
case
|
21
|
-
when
|
19
|
+
result, size = call %w[a( b+ c x\\ + y )] do |line, children, completions, offset|
|
20
|
+
case offset
|
21
|
+
when 2
|
22
22
|
line.should == 'b+'
|
23
23
|
children.should == []
|
24
24
|
completions.should == ['c']
|
25
25
|
block_invocations += 1
|
26
26
|
'b+c'
|
27
|
-
when
|
27
|
+
when 5
|
28
28
|
line.should == 'x\\'
|
29
29
|
children.should == []
|
30
30
|
completions.should == ['+', 'y']
|
31
31
|
block_invocations += 10
|
32
32
|
'x\\+y'
|
33
|
-
when
|
33
|
+
when 6
|
34
34
|
line.should == 'a('
|
35
35
|
children.should == ['b+c', 'x\\+y']
|
36
36
|
completions.should == [')']
|
37
37
|
block_invocations += 100
|
38
38
|
'ALL DONE!'
|
39
39
|
else
|
40
|
-
raise "
|
40
|
+
raise "offset: #{offset.inspect}"
|
41
41
|
end
|
42
42
|
end
|
43
43
|
result.should == 'ALL DONE!'
|
44
|
+
size.should == 7
|
44
45
|
block_invocations.should == 111
|
45
46
|
end
|
46
47
|
|
@@ -53,15 +54,15 @@ describe SeeingIsBelieving::ExpressionList do
|
|
53
54
|
' end',
|
54
55
|
'end',
|
55
56
|
]
|
56
|
-
result = call expressions do |line, children, completions,
|
57
|
-
case
|
58
|
-
when
|
57
|
+
result, size = call expressions do |line, children, completions, offset|
|
58
|
+
case offset
|
59
|
+
when 2
|
59
60
|
[line, children, completions].should == [' n1 + n2', [], []]
|
60
61
|
block_invocations += 1
|
61
|
-
when
|
62
|
+
when 3
|
62
63
|
[line, children, completions].should == [' [2].map do |n2|', [' n1 + n2'], [' end']]
|
63
64
|
block_invocations += 10
|
64
|
-
when
|
65
|
+
when 4
|
65
66
|
[line, children, completions].should == ['[1].map do |n1|',
|
66
67
|
[" [2].map do |n2|\n n1 + n2\n end"],
|
67
68
|
['end']]
|
@@ -77,6 +78,7 @@ describe SeeingIsBelieving::ExpressionList do
|
|
77
78
|
" n1 + n2\n"\
|
78
79
|
" end\n"\
|
79
80
|
"end"
|
81
|
+
size.should == 5
|
80
82
|
end
|
81
83
|
|
82
84
|
|
@@ -87,12 +89,12 @@ describe SeeingIsBelieving::ExpressionList do
|
|
87
89
|
"n1 + n2",
|
88
90
|
"end end",
|
89
91
|
]
|
90
|
-
result = call expressions do |line, children, completions,
|
91
|
-
case
|
92
|
-
when
|
92
|
+
result, size = call expressions do |line, children, completions, offset|
|
93
|
+
case offset
|
94
|
+
when 2
|
93
95
|
[line, children, completions].should == ["n1 + n2", [], []]
|
94
96
|
block_invocations += 1
|
95
|
-
when
|
97
|
+
when 3
|
96
98
|
# not really sure what this *should* be like, but if this is the result,
|
97
99
|
# then it will work for the use cases I need it for
|
98
100
|
[line, *children, *completions].should == ["[1].map do |n1|",
|
@@ -101,7 +103,7 @@ describe SeeingIsBelieving::ExpressionList do
|
|
101
103
|
'end end']
|
102
104
|
block_invocations += 10
|
103
105
|
else
|
104
|
-
raise "
|
106
|
+
raise "offset: #{offset.inspect}"
|
105
107
|
end
|
106
108
|
[line, *children, *completions].join("\n")
|
107
109
|
end
|
@@ -109,14 +111,15 @@ describe SeeingIsBelieving::ExpressionList do
|
|
109
111
|
result.should == "[1].map do |n1|\n"\
|
110
112
|
"[2].map do |n2|\n"\
|
111
113
|
"n1 + n2\n"\
|
112
|
-
"end end"
|
114
|
+
"end end"
|
115
|
+
size.should == 4
|
113
116
|
end
|
114
117
|
|
115
118
|
example 'example: multiline strings with valid code in them' do
|
116
119
|
block_invocations = 0
|
117
|
-
call ["'", "1", "'"] do |*expressions,
|
120
|
+
call ["'", "1", "'"] do |*expressions, offset|
|
118
121
|
expressions.join('').should == "'1'"
|
119
|
-
|
122
|
+
offset.should == 2
|
120
123
|
block_invocations += 1
|
121
124
|
end
|
122
125
|
block_invocations.should == 1
|
@@ -124,9 +127,9 @@ describe SeeingIsBelieving::ExpressionList do
|
|
124
127
|
|
125
128
|
example 'example: multiline regexps with valid code in them' do
|
126
129
|
block_invocations = 0
|
127
|
-
call ['/', '1', '/'] do |*expressions,
|
130
|
+
call ['/', '1', '/'] do |*expressions, offset|
|
128
131
|
expressions.join('').should == "/1/"
|
129
|
-
|
132
|
+
offset.should == 2
|
130
133
|
block_invocations += 1
|
131
134
|
end
|
132
135
|
block_invocations.should == 1
|
@@ -134,9 +137,9 @@ describe SeeingIsBelieving::ExpressionList do
|
|
134
137
|
|
135
138
|
example "example: =begin/=end comments" do
|
136
139
|
block_invocations = 0
|
137
|
-
call ['=begin', '1', '=end'] do |*expressions,
|
140
|
+
call ['=begin', '1', '=end'] do |*expressions, offset|
|
138
141
|
expressions.join('').should == "=begin1=end"
|
139
|
-
|
142
|
+
offset.should == 2
|
140
143
|
block_invocations += 1
|
141
144
|
end
|
142
145
|
block_invocations.should == 1
|
@@ -144,31 +147,32 @@ describe SeeingIsBelieving::ExpressionList do
|
|
144
147
|
|
145
148
|
example "example: heredoc" do
|
146
149
|
pending 'Not sure how to do this, for now just catch it at a higher level' do
|
147
|
-
result = call ['strings = [<<A, <<-B]', '1', 'A', '2', ' B'] do |*expressions,
|
148
|
-
|
150
|
+
result, size = call ['strings = [<<A, <<-B]', '1', 'A', '2', ' B'] do |*expressions, offset|
|
151
|
+
offset.should == 1
|
149
152
|
expressions.should == ['strings = [<<A, <<B]']
|
150
153
|
'zomg!'
|
151
154
|
end
|
152
155
|
result.should == "zomg!\n1\nA\n2\n B"
|
156
|
+
size.should == 5
|
153
157
|
end
|
154
158
|
end
|
155
159
|
|
156
160
|
example "example: method invocations on next line" do
|
157
161
|
# example 1: consume the expression with lines after
|
158
|
-
list = list_for ['a', '.b', ' .c', 'irrelevant'] do |*expressions,
|
159
|
-
|
162
|
+
list = list_for ['a', '.b', ' .c', 'irrelevant'] do |*expressions, offset|
|
163
|
+
offset.should == 2
|
160
164
|
expressions.flatten.join('').should == 'a.b .c'
|
161
165
|
'a.b.c'
|
162
166
|
end
|
163
|
-
list.call.should == 'a.b.c'
|
167
|
+
list.call.should == ['a.b.c', 3]
|
164
168
|
|
165
169
|
# example 2: consume the expression with no lines after
|
166
|
-
list = list_for ['a', '.b'] do |*expressions,
|
167
|
-
|
170
|
+
list = list_for ['a', '.b'] do |*expressions, offset|
|
171
|
+
offset.should == 1
|
168
172
|
expressions.flatten.join('').should == 'a.b'
|
169
173
|
'result'
|
170
174
|
end
|
171
|
-
list.call.should == 'result'
|
175
|
+
list.call.should == ['result', 2]
|
172
176
|
end
|
173
177
|
|
174
178
|
example "example: smoke test debug option" do
|