seeing_is_believing 2.0.0.beta1 → 2.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/Readme.md +8 -20
  3. data/features/examples.feature +1 -3
  4. data/features/flags.feature +4 -12
  5. data/features/regression.feature +95 -1
  6. data/lib/seeing_is_believing.rb +17 -21
  7. data/lib/seeing_is_believing/binary.rb +3 -3
  8. data/lib/seeing_is_believing/binary/add_annotations.rb +86 -118
  9. data/lib/seeing_is_believing/binary/align_chunk.rb +22 -23
  10. data/lib/seeing_is_believing/binary/align_file.rb +10 -13
  11. data/lib/seeing_is_believing/binary/align_line.rb +0 -4
  12. data/lib/seeing_is_believing/binary/arg_parser.rb +11 -11
  13. data/lib/seeing_is_believing/binary/clean_body.rb +96 -0
  14. data/lib/seeing_is_believing/binary/comment_formatter.rb +55 -0
  15. data/lib/seeing_is_believing/binary/comment_lines.rb +37 -0
  16. data/lib/seeing_is_believing/binary/commentable_lines.rb +158 -0
  17. data/lib/seeing_is_believing/binary/rewrite_comments.rb +42 -0
  18. data/lib/seeing_is_believing/result.rb +2 -9
  19. data/lib/seeing_is_believing/the_matrix.rb +8 -8
  20. data/lib/seeing_is_believing/version.rb +1 -1
  21. data/lib/seeing_is_believing/{program_rewriter.rb → wrap_expressions.rb} +30 -22
  22. data/spec/binary/arg_parser_spec.rb +7 -7
  23. data/spec/binary/clean_body_spec.rb +217 -0
  24. data/spec/binary/comment_formatter_spec.rb +54 -0
  25. data/spec/binary/comment_lines_spec.rb +847 -0
  26. data/spec/binary/rewrite_comments_spec.rb +54 -0
  27. data/spec/seeing_is_believing_spec.rb +1 -2
  28. data/spec/{program_rewriter_spec.rb → wrap_expressions_spec.rb} +117 -40
  29. metadata +41 -56
  30. data/lib/seeing_is_believing/binary/line_formatter.rb +0 -47
  31. data/lib/seeing_is_believing/binary/remove_previous_annotations.rb +0 -75
  32. data/lib/seeing_is_believing/queue.rb +0 -55
  33. data/lib/seeing_is_believing/remove_inline_comments.rb +0 -46
  34. data/lib/seeing_is_believing/syntax_analyzer.rb +0 -61
  35. data/lib/seeing_is_believing/tracks_line_numbers_seen.rb +0 -19
  36. data/spec/binary/line_formatter_spec.rb +0 -53
  37. data/spec/binary/remove_previous_annotations_spec.rb +0 -198
  38. data/spec/queue_spec.rb +0 -80
  39. data/spec/syntax_analyzer_spec.rb +0 -56
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a743322b1fb2c802a3c3e76876a799b4dcaaeae9
4
+ data.tar.gz: d6e24494bf3967f3958e73aa7df22a09c960c089
5
+ SHA512:
6
+ metadata.gz: 49aa7ad618d82e0fad1902a7fe43489ea606df56ae932bb6e4802a70e70f4d1e28a871332d65bc42137954f4857eed385ee6621231633b5a51718e90e6d600bd
7
+ data.tar.gz: 11fdde4edaae47edf12ed0f2e19c8b3ec4c4e0a43125860dcb74b5a8193a8c497b5e5e3822425127cff5aadf7e0230632eeb8eb29f5db9da5caba443d80c4843
data/Readme.md CHANGED
@@ -141,6 +141,7 @@ Known Issues
141
141
  ============
142
142
 
143
143
  * `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
144
+ * `exit!` ignores callbacks that `SeeingIsBelieving` uses to communicate the results back to the main app. If you call it, `SeeingIsBelieving` will blow up. We could "fix" this by overriding it, but I feel like that would violate the meaning of `exit!`, so basically, just don't call that method.
144
145
 
145
146
  Todo
146
147
  ====
@@ -148,31 +149,18 @@ Todo
148
149
  * Add examples of invocations to the help screen
149
150
  * Add xmpfilter option to sublime text
150
151
  * Update TextMate examples to use same keys as sublime, add xmpfilter option on cmd+opt+N
151
- * Remove the SyntaxAnalyzer altogether!
152
152
  * How about if begin/rescue/end was able to record the result on the rescue section
153
153
  * Check how begin/rescue/end with multiple rescue blocks works
154
154
  * What about recording the result of a line inside of a string interpolation, e.g. "a#{\n1\n}b" could record line 2 is 1 and line 3 is "a\n1\nb"
155
155
  * Be able to clean an invalid file (used to be able to do this, but parser can't identify comments in an invalid file the way that I'm currently using it, cuke is still there, marked as @not-implemented)
156
156
  * Add a flag to allow you to just get the results so that it can be easily used without a Ruby runtime
157
-
158
- Up Next
159
- =======
160
-
161
- rename ProgramRewriter -> WrapExpressions
162
- find that fucking regex bug
163
- add the inspected result --debug output
164
- Fix high-level shit:
165
- remove all previous output except if -x flag is set, then leave `# =>`
166
- `gsub(/\s*$/, '')`
167
- run it through sib
168
- if -x flag is set
169
- for each comment
170
- if it is `# =>`, update it
171
- else
172
- printable_list = get a list of each line that is an actual end and has no comments with sib (can ignore heredocs b/c they will have no value)
173
- this list is like line_number => [col_number, character_number] (e.g. where to insert on that line)
174
- for each line, add it at that character location, adjusting from the col_number to pad it correctly
175
-
157
+ * Go through each cuke and spec, implementing however many not-implemented ones that we can
158
+ * Check %w and all the others
159
+ * Add a --shebang flag
160
+ * Make sure the examples in this readme all still make sense (mountain berry fields?)
161
+ * uhm, can we wrap the parser setup code in one place? `ack Parser::Source::Buffer`
162
+ * Make the fucking debugger not lazy
163
+ * Go through Peter's email about how to make the use of Parser better
176
164
 
177
165
  License
178
166
  =======
@@ -34,7 +34,6 @@ Feature: Running the binary successfully
34
34
  /a
35
35
  b/x
36
36
 
37
- # don't record heredocs b/c they're just too fucking different
38
37
  <<HERE
39
38
  is a doc
40
39
  HERE
@@ -88,8 +87,7 @@ Feature: Running the binary successfully
88
87
  /a
89
88
  b/x # => /a\n b/x
90
89
 
91
- # don't record heredocs b/c they're just too fucking different
92
- <<HERE # => "is a doc\n"
90
+ <<HERE # => "is a doc\n"
93
91
  is a doc
94
92
  HERE
95
93
 
@@ -485,7 +485,7 @@ Feature: Using flags
485
485
  # => "omg2"
486
486
  """
487
487
 
488
- # TODO: do we want to print the source without its comments?
488
+
489
489
  Scenario: --debug
490
490
  Given the file "simple_program.rb":
491
491
  """
@@ -496,19 +496,11 @@ Feature: Using flags
496
496
  When I run "seeing_is_believing --debug simple_program.rb"
497
497
  Then stderr is empty
498
498
  And the exit status is 0
499
- # source without comments
500
- # And stdout includes "SOURCE WITHOUT COMMENTS:"
501
- # And stdout includes:
502
- # """
503
- # # encoding: utf-8
504
- # 1
505
- # 2
506
- # """
507
- # translated program
508
499
  And stdout includes "TRANSLATED PROGRAM:"
509
- And stdout includes "$seeing_is_believing_current_result"
510
- # result
500
+ And stdout includes "$SiB"
511
501
  And stdout includes "RESULT:"
502
+ And stdout includes "@results="
503
+ And stdout includes "OUTPUT:"
512
504
  And stdout includes:
513
505
  """
514
506
  # encoding: utf-8
@@ -164,7 +164,6 @@ Feature:
164
164
  'ç' # => "ç"
165
165
  """
166
166
 
167
- @not-implemented
168
167
  Scenario: Some strings look like comments
169
168
  Given the file "strings_that_look_like_comments.rb":
170
169
  """
@@ -177,3 +176,98 @@ Feature:
177
176
  "1
178
177
  #{2}" # => "1\n 2"
179
178
  """
179
+
180
+ Scenario: Kori's bug (Issue #11)
181
+ Given the file "koris_bug.rb":
182
+ """
183
+ class CreditCard
184
+
185
+ end
186
+
187
+ describe CreditCard do
188
+
189
+ end
190
+ """
191
+ When I run "seeing_is_believing koris_bug.rb"
192
+ Then stdout is:
193
+ """
194
+ class CreditCard
195
+
196
+ end
197
+
198
+ describe CreditCard do # ~> NoMethodError: undefined method `describe' for main:Object
199
+
200
+ end
201
+
202
+ # ~> NoMethodError
203
+ # ~> undefined method `describe' for main:Object
204
+ # ~>
205
+ # ~> koris_bug.rb:5:in `<main>'
206
+ """
207
+
208
+ Scenario: lambda-style fibonacci generator
209
+ Given the file "lambda_style_fib_gen.rb":
210
+ """
211
+ class Proc
212
+ def inspect
213
+ "<PROC>"
214
+ end
215
+ end
216
+
217
+ generic_fib_gen = -> current, prev {
218
+ -> {
219
+ [(current+prev), generic_fib_gen.(current+prev, current)]
220
+ }
221
+ }
222
+
223
+ fib_gen = generic_fib_gen.(1, -1)
224
+ n, fib_gen = fib_gen.()
225
+ n, fib_gen = fib_gen.()
226
+ n, fib_gen = fib_gen.()
227
+ """
228
+ When I run "seeing_is_believing lambda_style_fib_gen.rb"
229
+ Then stdout is:
230
+ """
231
+ class Proc
232
+ def inspect
233
+ "<PROC>" # => "<PROC>", "<PROC>", "<PROC>", "<PROC>", "<PROC>", "<PROC>", "<PROC>", "<PROC>", "<PROC>", "<PROC>", "<PROC>", "<PROC>"
234
+ end
235
+ end
236
+
237
+ generic_fib_gen = -> current, prev {
238
+ -> {
239
+ [(current+prev), generic_fib_gen.(current+prev, current)] # => [0, <PROC>], [1, <PROC>], [1, <PROC>]
240
+ } # => <PROC>, <PROC>, <PROC>, <PROC>
241
+ } # => <PROC>
242
+
243
+ fib_gen = generic_fib_gen.(1, -1) # => <PROC>
244
+ n, fib_gen = fib_gen.() # => [0, <PROC>]
245
+ n, fib_gen = fib_gen.() # => [1, <PROC>]
246
+ n, fib_gen = fib_gen.() # => [1, <PROC>]
247
+ """
248
+
249
+ Scenario: Repeated invocations
250
+ When I run "echo 'puts 1' | seeing_is_believing | seeing_is_believing"
251
+ Then stdout is:
252
+ """
253
+ puts 1 # => nil
254
+
255
+ # >> 1
256
+ """
257
+
258
+ Scenario: Heredoc at the end test
259
+ Given the file "heredoc_at_the_end.rb":
260
+ """
261
+ puts(<<A)
262
+ omg
263
+ A
264
+ """
265
+ When I run "seeing_is_believing heredoc_at_the_end.rb"
266
+ Then stdout is:
267
+ """
268
+ puts(<<A) # => nil
269
+ omg
270
+ A
271
+
272
+ # >> omg
273
+ """
@@ -2,18 +2,14 @@ require 'stringio'
2
2
  require 'tmpdir'
3
3
  require 'timeout'
4
4
 
5
- require 'seeing_is_believing/queue'
6
5
  require 'seeing_is_believing/result'
7
6
  require 'seeing_is_believing/version'
8
7
  require 'seeing_is_believing/debugger'
9
- require 'seeing_is_believing/remove_inline_comments'
10
8
  require 'seeing_is_believing/evaluate_by_moving_files'
11
- require 'seeing_is_believing/program_rewriter'
12
- require 'seeing_is_believing/syntax_analyzer' # can we get rid of this?
9
+ require 'seeing_is_believing/wrap_expressions'
13
10
 
14
11
  # might not work on windows b/c of assumptions about line ends
15
12
  class SeeingIsBelieving
16
- include TracksLineNumbersSeen
17
13
  BLANK_REGEX = /\A\s*\Z/
18
14
 
19
15
  def self.call(*args)
@@ -34,27 +30,14 @@ class SeeingIsBelieving
34
30
 
35
31
  def call
36
32
  @memoized_result ||= begin
37
- # must use newline after code, or comments will comment out rescue section
38
- # FIXME: IS THIS STILL TRUE?
39
- wrapped = ProgramReWriter.call "#@program\n",
40
- before_all: "begin;",
41
- after_all: "\n"\
42
- "rescue Exception;"\
43
- "line_number = $!.backtrace.grep(/\#{__FILE__}/).first[/:\\d+/][1..-1].to_i;"\
44
- "$seeing_is_believing_current_result.record_exception line_number, $!;"\
45
- "$seeing_is_believing_current_result.exitstatus = 1;"\
46
- "$seeing_is_believing_current_result.exitstatus = $!.status if $!.kind_of? SystemExit;"\
47
- "end",
48
- before_each: -> line_number { "($seeing_is_believing_current_result.record_result(#{line_number}, (" },
49
- after_each: -> line_number { ")))" }
50
- debugger.context("TRANSLATED PROGRAM") { wrapped }
51
- result = result_for wrapped
33
+ new_program = program_that_will_record_expressions
34
+ debugger.context("TRANSLATED PROGRAM") { new_program }
35
+ result = result_for new_program
52
36
  debugger.context("RESULT") { result.inspect }
53
37
  result
54
38
  end
55
39
  end
56
40
 
57
-
58
41
  private
59
42
 
60
43
  attr_reader :matrix_filename, :debugger
@@ -64,6 +47,19 @@ class SeeingIsBelieving
64
47
  StringIO.new string_or_stream
65
48
  end
66
49
 
50
+ def program_that_will_record_expressions
51
+ WrapExpressions.call "#@program\n",
52
+ before_all: "begin;",
53
+ after_all: ";rescue Exception;"\
54
+ "line_number = $!.backtrace.grep(/\#{__FILE__}/).first[/:\\d+/][1..-1].to_i;"\
55
+ "$SiB.record_exception line_number, $!;"\
56
+ "$SiB.exitstatus = 1;"\
57
+ "$SiB.exitstatus = $!.status if $!.kind_of? SystemExit;"\
58
+ "end",
59
+ before_each: -> line_number { "$SiB.record_result(#{line_number}, (" },
60
+ after_each: -> line_number { "))" }
61
+ end
62
+
67
63
  def result_for(program)
68
64
  Dir.mktmpdir "seeing_is_believing_temp_dir" do |dir|
69
65
  filename = @filename || File.join(dir, 'program.rb')
@@ -1,7 +1,7 @@
1
1
  require 'seeing_is_believing'
2
2
  require 'seeing_is_believing/binary/arg_parser'
3
3
  require 'seeing_is_believing/binary/add_annotations'
4
- require 'seeing_is_believing/binary/remove_previous_annotations'
4
+ require 'seeing_is_believing/binary/clean_body'
5
5
  require 'timeout'
6
6
 
7
7
 
@@ -94,7 +94,7 @@ class SeeingIsBelieving
94
94
  end
95
95
 
96
96
  def results
97
- printer.file_result
97
+ printer.results
98
98
  end
99
99
 
100
100
  def flags_have_errors?
@@ -155,7 +155,7 @@ class SeeingIsBelieving
155
155
  end
156
156
 
157
157
  def print_cleaned_program
158
- stdout.print RemovePreviousAnnotations.call body
158
+ stdout.print CleanBody.call(body, true)
159
159
  end
160
160
  end
161
161
  end
@@ -1,161 +1,129 @@
1
1
  require 'stringio'
2
- require 'seeing_is_believing/queue'
3
2
  require 'seeing_is_believing/has_exception'
4
- require 'seeing_is_believing/binary/line_formatter'
5
- require 'seeing_is_believing/binary/remove_previous_annotations'
3
+ require 'seeing_is_believing/binary/comment_formatter'
6
4
 
7
- # I think there is a bug where with xmpfilter_style set,
8
- # the exceptions won't be shown. But it's not totally clear
9
- # how to show them with this option set, anyway.
10
- # probably do what xmpfilter does and print them at the bottom
11
- # of the file (probably do this regardless of whether xmpfilter_style
12
- # is set)
13
- #
14
- # Would also be nice to support
15
- # 1 + 1
16
- # # => 2
17
- # style updates like xmpfilter does
5
+ require 'seeing_is_believing/binary/clean_body'
6
+ require 'seeing_is_believing/binary/rewrite_comments'
7
+ require 'seeing_is_believing/binary/comment_lines'
18
8
 
19
9
  class SeeingIsBelieving
20
10
  class Binary
21
11
  class AddAnnotations
22
12
  include HasException
23
13
 
24
- RESULT_PREFIX = '# =>'
25
- EXCEPTION_PREFIX = '# ~>'
26
- STDOUT_PREFIX = '# >>'
27
- STDERR_PREFIX = '# !>'
28
-
29
14
  def self.method_from_options(*args)
30
15
  define_method(args.first) { options.fetch *args }
31
16
  end
32
17
 
33
18
  method_from_options :filename, nil
34
- method_from_options :start_line
35
- method_from_options :end_line
36
- method_from_options :line_length, Float::INFINITY
37
- method_from_options :result_length, Float::INFINITY
19
+ method_from_options :start_line # rename: line_to_begin_recording
20
+ method_from_options :end_line # rename: line_to_end_recording
38
21
  method_from_options :xmpfilter_style
39
22
  method_from_options :debugger
40
23
 
41
- attr_accessor :file_result
42
- def initialize(body, options={})
43
- cleaned_body = RemovePreviousAnnotations.call body
44
- self.options = options
45
- self.body = (xmpfilter_style ? body : cleaned_body)
46
- self.file_result = SeeingIsBelieving.call body(),
47
- filename: (options[:as] || options[:filename]),
48
- require: options[:require],
49
- load_path: options[:load_path],
50
- encoding: options[:encoding],
51
- stdin: options[:stdin],
52
- timeout: options[:timeout],
53
- debugger: debugger
54
- self.alignment_strategy = options[:alignment_strategy].new cleaned_body, start_line, end_line
55
- end
56
-
57
- def new_body
58
- @new_body ||= ''
24
+ attr_accessor :results, :body
25
+ def initialize(uncleaned_body, options={})
26
+ self.options = options
27
+ self.body = CleanBody.call uncleaned_body, !xmpfilter_style
28
+ self.results = SeeingIsBelieving.call body,
29
+ filename: (options[:as] || options[:filename]),
30
+ require: options[:require],
31
+ load_path: options[:load_path],
32
+ encoding: options[:encoding],
33
+ stdin: options[:stdin],
34
+ timeout: options[:timeout],
35
+ debugger: debugger
59
36
  end
60
37
 
61
38
  def call
62
- @printed_program ||= begin
63
- # can we put the call to chomp into the line_queue initialization code?
64
- line_queue.until { |line, line_number| SyntaxAnalyzer.begins_data_segment?(line.chomp) }
65
- .each { |line, line_number| add_line line, line_number }
66
- add_stdout
67
- add_stderr
68
- add_exception
69
- add_remaining_lines
70
- if debugger.enabled?
71
- debugger.context("RESULT") { new_body }.to_s
39
+ @new_body ||= begin
40
+ # uhm, these basically look like strategies for commenting.
41
+ new_body = if xmpfilter_style
42
+ RewriteComments.call body do |line_number, line, whitespace, comment|
43
+ # FIXME: can we centralize these regexes?
44
+ if !comment[/\A#\s*=>/]
45
+ [whitespace, comment]
46
+ elsif line.empty?
47
+ # should go through comment formatter
48
+ [whitespace, "# => #{results[line_number-1].map { |result| result.gsub "\n", '\n' }.join(', ')}"] # FIXME: NEED TO CONSIDER THE LINE LENGTH
49
+ else
50
+ # should go through comment formatter
51
+ [whitespace, "# => #{results[line_number].map { |result| result.gsub "\n", '\n' }.join(', ')}"] # FIXME: NEED TO CONSIDER THE LINE LENGTH
52
+ end
53
+ end
72
54
  else
73
- new_body
55
+ alignment_strategy = options[:alignment_strategy].new body, start_line, end_line
56
+ CommentLines.call body do |line, line_number|
57
+ options = options().merge pad_to: alignment_strategy.line_length_for(line_number)
58
+ if line_number < start_line || end_line < line_number
59
+ ''
60
+ elsif results[line_number].has_exception?
61
+ exception = results[line_number].exception
62
+ result = sprintf "%s: %s", exception.class_name, exception.message.gsub("\n", '\n')
63
+ CommentFormatter.new(line.size, "# ~> ", result, options).call
64
+ elsif results[line_number].any?
65
+ result = results[line_number].map { |result| result.gsub "\n", '\n' }.join(', ')
66
+ CommentFormatter.call(line.size, "# => ", result, options)
67
+ else
68
+ ''
69
+ end
70
+ end
74
71
  end
75
- end
76
- end
77
72
 
78
- private
79
-
80
- attr_accessor :body, :options, :alignment_strategy
73
+ output = stdout_ouptut_for(results) <<
74
+ stderr_ouptut_for(results) <<
75
+ exception_output_for(results)
81
76
 
82
- def line_queue
83
- @line_queue ||= Queue.new &body.each_line.with_index(1).to_a.method(:shift)
84
- end
77
+ if new_body["\n__END__\n"]
78
+ new_body.sub! "\n__END__\n", "\n#{output}__END__\n"
79
+ else
80
+ new_body << "\n" unless new_body.end_with? "\n"
81
+ new_body << output
82
+ end
85
83
 
86
- # if we want to pull this into a strategy
87
- # we need to make available:
88
- # file_result, start_line, end_line, alignment_strategy, line_length, result_length
89
- def add_line(line, line_number)
90
- should_record = should_record? line, line_number
91
- if should_record && xmpfilter_style && line.strip =~ /^# =>/
92
- new_body << xmpfilter_update(line, file_result[line_number - 1]) # There is probably a bug in this since it doesn't go through the LineFormatter it can probably be to long
93
- elsif should_record && xmpfilter_style
94
- new_body << xmpfilter_update(line, file_result[line_number]) # There is probably a bug in this since it doesn't go through the LineFormatter it can probably be to long
95
- elsif should_record
96
- new_body << format_line(line.chomp, line_number, file_result[line_number])
97
- else
98
- new_body << line
84
+ new_body = if debugger.enabled?
85
+ debugger.context("OUTPUT") { new_body }.to_s
86
+ else
87
+ new_body
88
+ end
99
89
  end
100
90
  end
101
91
 
102
- def should_record?(line, line_number)
103
- (start_line <= line_number) &&
104
- (line_number <= end_line) &&
105
- (xmpfilter_style ? line =~ /# =>/ : # technically you could fuck this up with a line like "# =>", should later delegate to syntax analyzer
106
- !SyntaxAnalyzer.ends_in_comment?(line))
107
- end
92
+ private
108
93
 
109
- # again, this is too naive, should actually parse the comments and update them
110
- def xmpfilter_update(line, line_results)
111
- line.gsub /# =>.*?$/, "# => #{line_results.join(', ').gsub("\n", '\n')}"
112
- end
94
+ attr_accessor :body, :options, :alignment_strategy
113
95
 
114
- def add_stdout
115
- return unless file_result.has_stdout?
116
- new_body << "\n"
117
- file_result.stdout.each_line do |line|
118
- new_body << LineFormatter.new('', "#{STDOUT_PREFIX} ", line.chomp, options).call << "\n"
96
+ def stdout_ouptut_for(results)
97
+ return '' unless results.has_stdout?
98
+ output = "\n"
99
+ results.stdout.each_line do |line|
100
+ output << CommentFormatter.call(0, "# >> ", line.chomp, options()) << "\n"
119
101
  end
102
+ output
120
103
  end
121
104
 
122
- def add_stderr
123
- return unless file_result.has_stderr?
124
- new_body << "\n"
125
- file_result.stderr.each_line do |line|
126
- new_body << LineFormatter.new('', "#{STDERR_PREFIX} ", line.chomp, options).call << "\n"
105
+ def stderr_ouptut_for(results)
106
+ return '' unless results.has_stderr?
107
+ output = "\n"
108
+ results.stderr.each_line do |line|
109
+ output << CommentFormatter.call(0, "# !> ", line.chomp, options()) << "\n"
127
110
  end
111
+ output
128
112
  end
129
113
 
130
- def add_exception
131
- return unless file_result.has_exception?
132
- exception = file_result.exception
133
- new_body << "\n"
134
- new_body << LineFormatter.new('', "#{EXCEPTION_PREFIX} ", exception.class_name, options).call << "\n"
114
+ def exception_output_for(results)
115
+ return '' unless results.has_exception?
116
+ exception = results.exception
117
+ output = "\n"
118
+ output << CommentFormatter.new(0, "# ~> ", exception.class_name, options).call << "\n"
135
119
  exception.message.each_line do |line|
136
- new_body << LineFormatter.new('', "#{EXCEPTION_PREFIX} ", line.chomp, options).call << "\n"
120
+ output << CommentFormatter.new(0, "# ~> ", line.chomp, options).call << "\n"
137
121
  end
138
- new_body << "#{EXCEPTION_PREFIX}\n"
122
+ output << "# ~>\n"
139
123
  exception.backtrace.each do |line|
140
- new_body << LineFormatter.new('', "#{EXCEPTION_PREFIX} ", line.chomp, options).call << "\n"
124
+ output << CommentFormatter.new(0, "# ~> ", line.chomp, options).call << "\n"
141
125
  end
142
- end
143
-
144
- def add_remaining_lines
145
- line_queue.each { |line, line_number| new_body << line }
146
- end
147
-
148
- def format_line(line, line_number, line_results)
149
- options = options().merge pad_to: alignment_strategy.line_length_for(line_number)
150
- formatted_line = if line_results.has_exception?
151
- result = sprintf "%s: %s", line_results.exception.class_name, line_results.exception.message.gsub("\n", '\n')
152
- LineFormatter.new(line, "#{EXCEPTION_PREFIX} ", result, options).call
153
- elsif line_results.any?
154
- LineFormatter.new(line, "#{RESULT_PREFIX} ", line_results.join(', '), options).call
155
- else
156
- line
157
- end
158
- formatted_line + "\n"
126
+ output
159
127
  end
160
128
 
161
129
  end