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.
@@ -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
- # this can be refactored to use invoke
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
- result = invoke 'print File.expand_path __FILE__', filename: filename
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.9
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-04 00:00:00.000000000 Z
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: &70151257454580 !ruby/object:Gem::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: *70151257454580
24
+ version_requirements: *70252880676580
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &70151257453880 !ruby/object:Gem::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: *70151257453880
35
+ version_requirements: *70252880675820
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: cucumber
38
- requirement: &70151257449440 !ruby/object:Gem::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: *70151257449440
46
+ version_requirements: *70252880691520
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: ichannel
49
- requirement: &70151257448960 !ruby/object:Gem::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: *70151257448960
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