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
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'seeing_is_believing/binary/line_formatter'
|
2
|
+
|
3
|
+
describe SeeingIsBelieving::Binary::LineFormatter do
|
4
|
+
def result_for(line, separator, result, options={})
|
5
|
+
described_class.new(line, separator, result, options).call
|
6
|
+
end
|
7
|
+
|
8
|
+
specify 'it returns the consolidated result if there are no truncations' do
|
9
|
+
result_for('1', '=>', '12345').should == '1=>12345'
|
10
|
+
end
|
11
|
+
|
12
|
+
specify 'result_length truncates a result to the specified length, using elipses up to that length if appropriate' do
|
13
|
+
line = '1'
|
14
|
+
separator = '=>'
|
15
|
+
result = '12345'
|
16
|
+
result_for(line, separator, result, result_length: Float::INFINITY).should == '1=>12345'
|
17
|
+
result_for(line, separator, result, result_length: 7).should == '1=>12345'
|
18
|
+
result_for(line, separator, result, result_length: 6).should == '1=>1...'
|
19
|
+
result_for(line, separator, result, result_length: 5).should == '1=>...'
|
20
|
+
result_for(line, separator, result, result_length: 4).should == '1'
|
21
|
+
result_for(line, separator, result, result_length: 0).should == '1'
|
22
|
+
end
|
23
|
+
|
24
|
+
specify 'line_length truncates a result to the specified length, minus the length of the line' do
|
25
|
+
line = '1'
|
26
|
+
separator = '=>'
|
27
|
+
result = '12345'
|
28
|
+
result_for(line, separator, result).should == '1=>12345'
|
29
|
+
result_for(line, separator, result, line_length: Float::INFINITY).should == '1=>12345'
|
30
|
+
result_for(line, separator, result, line_length: 8).should == '1=>12345'
|
31
|
+
result_for(line, separator, result, line_length: 7).should == '1=>1...'
|
32
|
+
result_for(line, separator, result, line_length: 6).should == '1=>...'
|
33
|
+
result_for(line, separator, result, line_length: 5).should == '1'
|
34
|
+
result_for(line, separator, result, line_length: 0).should == '1'
|
35
|
+
end
|
36
|
+
|
37
|
+
specify 'source_length will alter the length that the line is displayed in' do
|
38
|
+
result_for('1', '=>', '2', source_length: 0).should == '1=>2'
|
39
|
+
result_for('1', '=>', '2', source_length: 1).should == '1=>2'
|
40
|
+
result_for('1', '=>', '2', source_length: 2).should == '1 =>2'
|
41
|
+
end
|
42
|
+
|
43
|
+
specify 'source_length is ignored when separator/result will not be printed' do
|
44
|
+
result_for('1', '=>', '12345', source_length: 2, line_length: 2).should == '1'
|
45
|
+
result_for('1', '=>', '12345', source_length: 2, result_length: 2).should == '1'
|
46
|
+
end
|
47
|
+
|
48
|
+
specify 'they can all work together' do
|
49
|
+
result_for('1', '=>', '12345', line_length: 100, result_length: 100, source_length: 2).should == '1 =>12345'
|
50
|
+
result_for('1', '=>', '12345', line_length: 8, result_length: 100, source_length: 2).should == '1 =>1...'
|
51
|
+
result_for('1', '=>', '12345', line_length: 100, result_length: 6, source_length: 2).should == '1 =>1...'
|
52
|
+
end
|
53
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
1
2
|
require 'seeing_is_believing'
|
2
3
|
require 'stringio'
|
3
4
|
|
@@ -198,13 +199,10 @@ describe SeeingIsBelieving do
|
|
198
199
|
result.stdout.should == filename
|
199
200
|
end
|
200
201
|
|
201
|
-
|
202
|
-
specify 'cwd is the directory of the file' do
|
202
|
+
specify 'cwd of the file is the cwd of the evaluating program' do
|
203
203
|
filename = File.join proving_grounds_dir, 'mah_file.rb'
|
204
204
|
FileUtils.rm_f filename
|
205
|
-
|
206
|
-
result = invoke 'print File.expand_path(Dir.pwd)', filename: filename
|
207
|
-
result.stdout.should == proving_grounds_dir
|
205
|
+
invoke('print File.expand_path(Dir.pwd)', filename: filename).stdout.should == Dir.pwd
|
208
206
|
end
|
209
207
|
|
210
208
|
it 'does not capture output from __END__ onward' do
|
@@ -231,4 +229,11 @@ describe SeeingIsBelieving do
|
|
231
229
|
values_for("1\n.even?").should == [[], ['false']]
|
232
230
|
values_for("1\n.even?\n__END__").should == [[], ['false']]
|
233
231
|
end
|
232
|
+
|
233
|
+
it 'does not record leading comments' do
|
234
|
+
values_for("# -*- coding: utf-8 -*-\n'ç'\n__LINE__").should == [[], ['"ç"'], ['3']]
|
235
|
+
values_for("=begin\n1\n=end\n=begin\n=end\n__LINE__").should == [[], [], [],
|
236
|
+
[], [],
|
237
|
+
['6']]
|
238
|
+
end
|
234
239
|
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.10
|
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-02-
|
12
|
+
date: 2013-02-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement: &
|
16
|
+
requirement: &70252880676580 !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: *70252880676580
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &70252880675820 !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: *70252880675820
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: cucumber
|
38
|
-
requirement: &
|
38
|
+
requirement: &70252880691520 !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: *70252880691520
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: ichannel
|
49
|
-
requirement: &
|
49
|
+
requirement: &70252880691040 !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: *70252880691040
|
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"
|
@@ -78,14 +78,15 @@ files:
|
|
78
78
|
- features/step_definitions/steps.rb
|
79
79
|
- features/support/env.rb
|
80
80
|
- lib/seeing_is_believing.rb
|
81
|
-
- lib/seeing_is_believing/arg_parser.rb
|
82
81
|
- lib/seeing_is_believing/binary.rb
|
82
|
+
- lib/seeing_is_believing/binary/arg_parser.rb
|
83
|
+
- lib/seeing_is_believing/binary/line_formatter.rb
|
84
|
+
- lib/seeing_is_believing/binary/print_results_next_to_lines.rb
|
83
85
|
- lib/seeing_is_believing/error.rb
|
84
86
|
- lib/seeing_is_believing/evaluate_by_moving_files.rb
|
85
87
|
- lib/seeing_is_believing/expression_list.rb
|
86
88
|
- lib/seeing_is_believing/hard_core_ensure.rb
|
87
89
|
- lib/seeing_is_believing/has_exception.rb
|
88
|
-
- lib/seeing_is_believing/print_results_next_to_lines.rb
|
89
90
|
- lib/seeing_is_believing/queue.rb
|
90
91
|
- lib/seeing_is_believing/result.rb
|
91
92
|
- lib/seeing_is_believing/syntax_analyzer.rb
|
@@ -97,6 +98,7 @@ files:
|
|
97
98
|
- spec/evaluate_by_moving_files_spec.rb
|
98
99
|
- spec/expression_list_spec.rb
|
99
100
|
- spec/hard_core_ensure_spec.rb
|
101
|
+
- spec/line_formatter_spec.rb
|
100
102
|
- spec/queue_spec.rb
|
101
103
|
- spec/seeing_is_believing_spec.rb
|
102
104
|
- spec/syntax_analyzer_spec.rb
|
@@ -135,6 +137,7 @@ test_files:
|
|
135
137
|
- spec/evaluate_by_moving_files_spec.rb
|
136
138
|
- spec/expression_list_spec.rb
|
137
139
|
- spec/hard_core_ensure_spec.rb
|
140
|
+
- spec/line_formatter_spec.rb
|
138
141
|
- spec/queue_spec.rb
|
139
142
|
- spec/seeing_is_believing_spec.rb
|
140
143
|
- spec/syntax_analyzer_spec.rb
|
@@ -1,94 +0,0 @@
|
|
1
|
-
class SeeingIsBelieving
|
2
|
-
class ArgParser
|
3
|
-
def self.parse(args)
|
4
|
-
new(args).call
|
5
|
-
end
|
6
|
-
|
7
|
-
attr_accessor :args
|
8
|
-
|
9
|
-
def initialize(args)
|
10
|
-
self.args = args
|
11
|
-
self.filenames = []
|
12
|
-
end
|
13
|
-
|
14
|
-
def call
|
15
|
-
@result ||= begin
|
16
|
-
until args.empty?
|
17
|
-
case (arg = args.shift)
|
18
|
-
|
19
|
-
# help screen
|
20
|
-
when '-h', '--help'
|
21
|
-
options[:help] = self.class.help_screen
|
22
|
-
|
23
|
-
# start line
|
24
|
-
when '-l', '--start-line'
|
25
|
-
start_line = args.shift
|
26
|
-
i_start_line = start_line.to_i
|
27
|
-
if i_start_line.to_s == start_line && !i_start_line.zero?
|
28
|
-
options[:start_line] = start_line.to_i
|
29
|
-
else
|
30
|
-
options[:errors] << "#{arg} expects a positive integer argument"
|
31
|
-
end
|
32
|
-
|
33
|
-
# end line
|
34
|
-
when '-L', '--end-line'
|
35
|
-
end_line = args.shift
|
36
|
-
if end_line.to_i.to_s == end_line
|
37
|
-
options[:end_line] = end_line.to_i
|
38
|
-
else
|
39
|
-
options[:errors] << "#{arg} expect an integer argument"
|
40
|
-
end
|
41
|
-
|
42
|
-
# unknown flags
|
43
|
-
when /^-/
|
44
|
-
options[:errors] << "Unknown option: #{arg.inspect}"
|
45
|
-
|
46
|
-
# filenames
|
47
|
-
else
|
48
|
-
filenames << arg
|
49
|
-
options[:filename] = arg
|
50
|
-
end
|
51
|
-
end
|
52
|
-
normalize_and_validate
|
53
|
-
options
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
|
59
|
-
attr_accessor :filenames
|
60
|
-
|
61
|
-
def normalize_and_validate
|
62
|
-
if 1 < filenames.size
|
63
|
-
options[:errors] << "Can only have one filename, but had: #{filenames.map(&:inspect).join ', '}"
|
64
|
-
end
|
65
|
-
|
66
|
-
if options[:end_line] < options[:start_line]
|
67
|
-
options[:start_line], options[:end_line] = options[:end_line], options[:start_line]
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def options
|
72
|
-
@options ||= {
|
73
|
-
filename: nil,
|
74
|
-
errors: [],
|
75
|
-
start_line: 1,
|
76
|
-
end_line: Float::INFINITY,
|
77
|
-
}
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def ArgParser.help_screen
|
82
|
-
<<HELP_SCREEN
|
83
|
-
Usage: #{$0} [options] [filename]
|
84
|
-
|
85
|
-
#{$0} is a program and library that will evaluate a Ruby file and capture/display the results.
|
86
|
-
|
87
|
-
If no filename is provided, the binary will read the program from standard input.
|
88
|
-
|
89
|
-
-l, --start-line # line number to begin showing results on
|
90
|
-
-L, --end-line # line number to stop showing results on
|
91
|
-
-h, --help # this help screen
|
92
|
-
HELP_SCREEN
|
93
|
-
end
|
94
|
-
end
|
@@ -1,117 +0,0 @@
|
|
1
|
-
require 'seeing_is_believing'
|
2
|
-
require 'seeing_is_believing/queue'
|
3
|
-
require 'seeing_is_believing/has_exception'
|
4
|
-
|
5
|
-
class SeeingIsBelieving
|
6
|
-
class PrintResultsNextToLines
|
7
|
-
include HasException
|
8
|
-
|
9
|
-
STDOUT_PREFIX = '# >>'
|
10
|
-
STDERR_PREFIX = '# !>'
|
11
|
-
EXCEPTION_PREFIX = '# ~>'
|
12
|
-
RESULT_PREFIX = '# =>'
|
13
|
-
|
14
|
-
def initialize(body, stdin, options={})
|
15
|
-
self.body = remove_previous_output_from body
|
16
|
-
self.stdin = stdin
|
17
|
-
self.filename = options.fetch :filename, nil
|
18
|
-
self.start_line = options.fetch :start_line
|
19
|
-
self.end_line = options.fetch :end_line
|
20
|
-
end
|
21
|
-
|
22
|
-
def new_body
|
23
|
-
@new_body ||= ''
|
24
|
-
end
|
25
|
-
|
26
|
-
def call
|
27
|
-
evaluate_program
|
28
|
-
inherit_exception
|
29
|
-
add_each_line_until_start_or_data_segment
|
30
|
-
add_lines_with_results_until_end_or_data_segment
|
31
|
-
add_lines_until_data_segment
|
32
|
-
add_stdout
|
33
|
-
add_stderr
|
34
|
-
add_remaining_lines
|
35
|
-
return new_body
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
attr_accessor :body, :filename, :file_result, :stdin, :start_line, :end_line
|
41
|
-
|
42
|
-
def evaluate_program
|
43
|
-
self.file_result = SeeingIsBelieving.new(body, filename: filename, stdin: stdin).call
|
44
|
-
end
|
45
|
-
|
46
|
-
def inherit_exception
|
47
|
-
self.exception = file_result.exception
|
48
|
-
end
|
49
|
-
|
50
|
-
def add_each_line_until_start_or_data_segment
|
51
|
-
line_queue.until { |line, line_number| line_number == start_line || start_of_data_segment?(line) }
|
52
|
-
.each { |line, line_number| new_body << line }
|
53
|
-
end
|
54
|
-
|
55
|
-
def add_lines_with_results_until_end_or_data_segment
|
56
|
-
line_queue.until { |line, line_number| end_line < line_number || start_of_data_segment?(line) }
|
57
|
-
.each { |line, line_number| new_body << format_line(line.chomp, file_result[line_number]) }
|
58
|
-
end
|
59
|
-
|
60
|
-
def add_lines_until_data_segment
|
61
|
-
line_queue.until { |line, line_number| start_of_data_segment?(line) }
|
62
|
-
.each { |line, line_number| new_body << line }
|
63
|
-
end
|
64
|
-
|
65
|
-
def add_remaining_lines
|
66
|
-
line_queue.each { |line, line_number| new_body << line }
|
67
|
-
end
|
68
|
-
|
69
|
-
def line_queue
|
70
|
-
@line_queue ||= Queue.new &body.each_line.with_index(1).to_a.method(:shift)
|
71
|
-
end
|
72
|
-
|
73
|
-
def start_of_data_segment?(line)
|
74
|
-
line.chomp == '__END__'
|
75
|
-
end
|
76
|
-
|
77
|
-
# max line length of the lines to output (exempting coments) + 2 spaces for padding
|
78
|
-
def line_length
|
79
|
-
@line_length ||= 2 + body.each_line
|
80
|
-
.map(&:chomp)
|
81
|
-
.select.with_index(1) { |line, index| start_line <= index && index <= end_line }
|
82
|
-
.take_while { |line| not start_of_data_segment? line }
|
83
|
-
.select { |line| not (line == "=begin") .. (line == "=end") }
|
84
|
-
.reject { |line| SyntaxAnalyzer.ends_in_comment? line }
|
85
|
-
.map(&:length)
|
86
|
-
.max
|
87
|
-
end
|
88
|
-
|
89
|
-
def remove_previous_output_from(string)
|
90
|
-
string.gsub(/\s+(#{EXCEPTION_PREFIX}|#{RESULT_PREFIX}).*?$/, '')
|
91
|
-
.gsub(/\n?(^#{STDOUT_PREFIX}[^\n]*\r?\n?)+/m, '')
|
92
|
-
.gsub(/\n?(^#{STDERR_PREFIX}[^\n]*\r?\n?)+/m, '')
|
93
|
-
end
|
94
|
-
|
95
|
-
def add_stdout
|
96
|
-
return unless file_result.has_stdout?
|
97
|
-
new_body << "\n"
|
98
|
-
file_result.stdout.each_line { |line| new_body << "#{STDOUT_PREFIX} #{line}" }
|
99
|
-
end
|
100
|
-
|
101
|
-
def add_stderr
|
102
|
-
return unless file_result.has_stderr?
|
103
|
-
new_body << "\n"
|
104
|
-
file_result.stderr.each_line { |line| new_body << "#{STDERR_PREFIX} #{line}" }
|
105
|
-
end
|
106
|
-
|
107
|
-
def format_line(line, line_results)
|
108
|
-
if line_results.has_exception?
|
109
|
-
sprintf "%-#{line_length}s#{EXCEPTION_PREFIX} %s: %s\n", line, line_results.exception.class, line_results.exception.message
|
110
|
-
elsif line_results.any?
|
111
|
-
sprintf "%-#{line_length}s#{RESULT_PREFIX} %s\n", line, line_results.join(', ')
|
112
|
-
else
|
113
|
-
line + "\n"
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|