seeing_is_believing 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|