Class: RSpec::TapBaseFormatter
- Inherits:
-
Core::Formatters::BaseFormatter
- Object
- Core::Formatters::BaseFormatter
- RSpec::TapBaseFormatter
- Defined in:
- lib/rspec/ontap.rb
Constant Summary collapse
- REVISION =
TAP-Y/J Revision
4
Instance Attribute Summary collapse
-
#example_group_stack ⇒ Object
Returns the value of attribute example_group_stack.
Instance Method Summary collapse
- #capture_io ⇒ Object private
- #captured_output ⇒ Object private
-
#code_snippet(file, line) ⇒ Object
private
Returns a String of source code.
-
#dump_summary(duration, example_count, failure_count, pending_count) ⇒ Object
This method is invoked after the dumping of examples and failures.
- #example_failed(example) ⇒ Object
-
#example_group_finished(example_group) ⇒ Object
This method is invoked at the end of the execution of each example group.
-
#example_group_started(example_group) ⇒ Object
This method is invoked at the beginning of the execution of each example group.
- #example_passed(example) ⇒ Object
- #example_pending(example) ⇒ Object
- #example_started(example) ⇒ Object
-
#initialize(output) ⇒ TapBaseFormatter
constructor
A new instance of TapBaseFormatter.
- #message(message) ⇒ Object
-
#parse_source_location(caller) ⇒ Object
private
Parse source location from caller, caller or an Exception object.
- #reset_output ⇒ Object private
-
#seed(number) ⇒ Object
This gets invoked after the summary if option is set to do so.
-
#source(file) ⇒ Object
private
Cache source file text.
-
#start(example_count) ⇒ Object
This method is invoked before any examples are run, right after they have all been collected.
Constructor Details
#initialize(output) ⇒ TapBaseFormatter
Returns a new instance of TapBaseFormatter.
19 20 21 22 |
# File 'lib/rspec/ontap.rb', line 19 def initialize(output) super(output) @example_group_stack = [] end |
Instance Attribute Details
#example_group_stack ⇒ Object
Returns the value of attribute example_group_stack.
14 15 16 |
# File 'lib/rspec/ontap.rb', line 14 def example_group_stack @example_group_stack end |
Instance Method Details
#capture_io ⇒ Object (private)
325 326 327 328 329 330 331 332 333 334 335 336 |
# File 'lib/rspec/ontap.rb', line 325 def capture_io ostdout, ostderr = $stdout, $stderr cstdout, cstderr = StringIO.new, StringIO.new $stdout, $stderr = cstdout, cstderr yield return cstdout.string.chomp("\n"), cstderr.string.chomp("\n") ensure $stdout = ostdout $stderr = ostderr end |
#captured_output ⇒ Object (private)
310 311 312 313 314 315 316 317 318 319 320 321 322 |
# File 'lib/rspec/ontap.rb', line 310 def captured_output stdout = @_newout.string.chomp("\n") stderr = @_newerr.string.chomp("\n") doc = {} doc['stdout'] = stdout unless stdout.empty? doc['stderr'] = stderr unless stderr.empty? $stdout = @_oldout $stderr = @_olderr return doc end |
#code_snippet(file, line) ⇒ Object (private)
Returns a String of source code.
259 260 261 262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/rspec/ontap.rb', line 259 def code_snippet(file, line) s = [] if File.file?(file) source = source(file) radius = 2 # TODO: make customizable (number of surrounding lines to show) region = [line - radius, 1].max .. [line + radius, source.length].min s = region.map do |n| {n => source[n-1].chomp} end end return s end |
#dump_summary(duration, example_count, failure_count, pending_count) ⇒ Object
This method is invoked after the dumping of examples and failures.
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/rspec/ontap.rb', line 217 def dump_summary(duration, example_count, failure_count, pending_count) super(duration, example_count, failure_count, pending_count) error_count = 0 @failed_examples.each do |e| if RSpec::Expectations::ExpectationNotMetError === e.exception #failure_count += 1 else failure_count -= 1 error_count += 1 end end passing_count = example_count - failure_count - error_count - pending_count doc = { 'type' => 'final', 'time' => duration, 'counts' => { 'total' => example_count, 'pass' => passing_count, 'fail' => failure_count, 'error' => error_count, 'omit' => 0, 'todo' => pending_count } } return doc end |
#example_failed(example) ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/rspec/ontap.rb', line 143 def example_failed(example) super(example) file, line = example.location.split(':') file = self.class.relative_path(file) line = line.to_i if RSpec::Expectations::ExpectationNotMetError === example.exception status = 'fail' if md = /expected:\s*(.*?)\n\s*got:\s*(.*?)\s+/.match(example.exception.to_s) expected, returned = md[1], md[2] else expected, returned = nil, nil end else status = 'error' end backtrace = format_backtrace(example.exception.backtrace, example) efile, eline = parse_source_location(backtrace) doc = { 'type' => 'test', 'subtype' => 'it', 'status' => status, 'label' => "#{example.description}", #'setup' => "foo instance", 'file' => file, 'line' => line, 'source' => source(file)[line-1].strip, 'snippet' => code_snippet(file, line), #'coverage' => #{ # 'file' => lib/foo.rb # 'line' => 11..13 # 'code' => Foo#* #} } if expected or returned doc.update( 'expected' => expected, 'returned' => returned, ) end doc.update( 'exception' => { 'message' => example.exception.to_s.strip, 'class' => example.exception.class.name, 'file' => efile, 'line' => eline, 'source' => source(efile)[eline-1].strip, 'snippet' => code_snippet(efile, eline), 'backtrace' => backtrace }, 'time' => Time.now - @start_time ) doc.update(captured_output) return doc end |
#example_group_finished(example_group) ⇒ Object
This method is invoked at the end of the execution of each example group. example_group
is the example_group.
68 69 70 |
# File 'lib/rspec/ontap.rb', line 68 def example_group_finished(example_group) @example_group_stack.pop end |
#example_group_started(example_group) ⇒ Object
This method is invoked at the beginning of the execution of each example group. example_group
is the example_group.
The next method to be invoked after this is example_passed
, example_pending
, or example_finished
54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/rspec/ontap.rb', line 54 def example_group_started(example_group) super(example_group) #@example_group = example_group doc = { 'type' => 'case', 'subtype' => 'describe', 'label' => "#{example_group.description}", 'level' => @example_group_stack.size } @example_group_stack << example_group return doc end |
#example_passed(example) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/rspec/ontap.rb', line 80 def example_passed(example) super(example) file, line = example.location.split(':') file = self.class.relative_path(file) line = line.to_i doc = { 'type' => 'test', 'subtype' => 'it', 'status' => 'pass', #'setup': foo instance 'label' => "#{example.description}", #'expected' => 2 #'returned' => 2 'file' => file, 'line' => line, 'source' => source(file)[line-1].strip, 'snippet' => code_snippet(file, line), #'coverage' => { # file: lib/foo.rb # line: 11..13 # code: Foo#* #} 'time' => Time.now - @start_time } doc.update(captured_output) return doc end |
#example_pending(example) ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/rspec/ontap.rb', line 113 def example_pending(example) super(example) file, line = example.location.split(':') file = self.class.relative_path(file) line = line.to_i doc = { 'type' => 'test', 'subtype' => 'it', 'status' => 'todo', #'setup': foo instance 'label' => "#{example.description}", 'file' => file, 'line' => line, 'source' => source(file)[line-1].strip, 'snippet' => code_snippet(file, line), #'coverage' => { # file: lib/foo.rb # line: 11..13 # code: Foo#* #} 'time' => Time.now - @start_time } doc.update(captured_output) return doc end |
#example_started(example) ⇒ Object
73 74 75 76 77 |
# File 'lib/rspec/ontap.rb', line 73 def example_started(example) examples << example # set up stdout and stderr to be captured reset_output end |
#message(message) ⇒ Object
Is this a note?
210 211 |
# File 'lib/rspec/ontap.rb', line 210 def () end |
#parse_source_location(caller) ⇒ Object (private)
Parse source location from caller, caller or an Exception object.
284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'lib/rspec/ontap.rb', line 284 def parse_source_location(caller) case caller when Exception trace = caller.backtrace #.reject{ |bt| bt =~ INTERNALS } caller = trace.first when Array caller = caller.first end caller =~ /(.+?):(\d+(?=:|\z))/ or return "" source_file, source_line = $1, $2.to_i return source_file, source_line end |
#reset_output ⇒ Object (private)
298 299 300 301 302 303 304 305 306 307 |
# File 'lib/rspec/ontap.rb', line 298 def reset_output @_oldout = $stdout @_olderr = $stderr @_newout = StringIO.new @_newerr = StringIO.new $stdout = @_newout $stderr = @_newerr end |
#seed(number) ⇒ Object
This gets invoked after the summary if option is set to do so. def dump_pending end
252 253 254 |
# File 'lib/rspec/ontap.rb', line 252 def seed(number) @seed = number end |
#source(file) ⇒ Object (private)
Cache source file text. This is only used if the TAP-Y stream doesn not provide a snippet and the test file is locatable.
276 277 278 279 280 281 |
# File 'lib/rspec/ontap.rb', line 276 def source(file) @_source_cache ||= {} @_source_cache[file] ||= ( File.readlines(file) ) end |
#start(example_count) ⇒ Object
This method is invoked before any examples are run, right after they have all been collected. This can be useful for special formatters that need to provide progress on feedback (graphical ones)
This will only be invoked once, and the next one to be invoked is #example_group_started
32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/rspec/ontap.rb', line 32 def start(example_count) super(example_count) @start_time = Time.now doc = { 'type' => 'suite', 'start' => @start_time.strftime('%Y-%m-%d %H:%M:%S'), 'count' => example_count, 'seed' => @seed, 'rev' => REVISION } return doc end |