Class: TapOut::Reporters::Abstract
- Inherits:
-
Object
- Object
- TapOut::Reporters::Abstract
- Defined in:
- lib/tapout/reporters/abstract.rb
Overview
The Abstract class serves as a base class for all reporters. Reporters must sublcass Abstract in order to be added the the Reporters Index.
TODO: Simplify this class and have the sublcasses handle more of the load.
Direct Known Subclasses
Constant Summary collapse
- INTERNALS =
/(lib|bin)#{Regexp.escape(File::SEPARATOR)}tapout/
Class Method Summary collapse
-
.inherited(subclass) ⇒ Object
When Abstract is inherited it saves a reference to it in ‘Reporters.index`.
Instance Method Summary collapse
- #<<(entry) ⇒ Object
-
#clean_backtrace(backtrace) ⇒ Object
Clean the backtrace of any reference to ko/ paths and code.
-
#code_snippet(entry) ⇒ Object
Returns a String of source code.
-
#err(entry) ⇒ Object
Handle test with error status.
-
#exit_code ⇒ Object
Exit code.
-
#fail(entry) ⇒ Object
Handle test with fail status.
-
#finish_case(entry) ⇒ Object
When a test case is complete.
-
#finish_suite(entry) ⇒ Object
Handle footer.
-
#handle(entry) ⇒ Object
Handler method.
-
#initialize ⇒ Abstract
constructor
New reporter.
-
#note(entry) ⇒ Object
Handle an arbitray note.
-
#omit(entry) ⇒ Object
Handle test with omit status.
-
#parse_source_location(caller) ⇒ Object
Parse source location from caller, caller or an Exception object.
-
#pass(entry) ⇒ Object
Handle test with pass status.
-
#skip(entry) ⇒ Object
Handle test with skip or pending status.
-
#source(file) ⇒ Object
Cache source file text.
-
#start_case(entry) ⇒ Object
At the start of a new test case.
-
#start_suite(entry) ⇒ Object
Handle header.
-
#tally(entry) ⇒ Object
TODO: get the tally’s from the footer entry ?.
-
#test(entry) ⇒ Object
Handle test.
Constructor Details
#initialize ⇒ Abstract
New reporter.
32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/tapout/reporters/abstract.rb', line 32 def initialize @passed = [] @failed = [] @raised = [] @skipped = [] @omitted = [] @source = {} @previous_case = nil @exit_code = 0 # assume passing end |
Class Method Details
Instance Method Details
#<<(entry) ⇒ Object
50 51 52 |
# File 'lib/tapout/reporters/abstract.rb', line 50 def <<(entry) handle(entry) end |
#clean_backtrace(backtrace) ⇒ Object
Clean the backtrace of any reference to ko/ paths and code.
181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/tapout/reporters/abstract.rb', line 181 def clean_backtrace(backtrace) trace = backtrace.reject{ |bt| bt =~ INTERNALS } trace = trace.map do |bt| if i = bt.index(':in') bt[0...i] else bt end end trace = backtrace if trace.empty? trace = trace.map{ |bt| bt.sub(Dir.pwd+File::SEPARATOR,'') } trace end |
#code_snippet(entry) ⇒ Object
Returns a String of source code.
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 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 247 248 249 |
# File 'lib/tapout/reporters/abstract.rb', line 196 def code_snippet(entry) file = entry['file'] line = entry['line'] snippet = entry['snippet'] s = [] case snippet when String lines = snippet.lines.to_a index = line - ((lines.size - 1) / 2) lines.each do |line| s << [index, line] index += 1 end when Array snippet.each do |h| s << [h.keys.first, h.values.first] end else ##backtrace = exception.backtrace.reject{ |bt| bt =~ INTERNALS } ##backtrace.first =~ /(.+?):(\d+(?=:|\z))/ or return "" #caller =~ /(.+?):(\d+(?=:|\z))/ or return "" #source_file, source_line = $1, $2.to_i if file && File.file?(file) source = source(file) radius = 3 # number of surrounding lines to show region = [line - radius, 1].max .. [line + radius, source.length].min #len = region.last.to_s.length s = region.map do |n| #format % [n, source[n-1].chomp] [n, source[n-1].chomp] end end end len = s.map{ |(n,t)| n }.max.to_s.length # ensure proper alignment by zero-padding line numbers format = " %5s %0#{len}d %s" #s = s.map{|n,t|[n,t]}.sort{|a,b|a[0]<=>b[0]} pretty = s.map do |(n,t)| format % [('=>' if n == line), n, t.rstrip] end #.unshift "[#{region.inspect}] in #{source_file}" return pretty end |
#err(entry) ⇒ Object
Handle test with error status.
115 116 117 |
# File 'lib/tapout/reporters/abstract.rb', line 115 def err(entry) @raised << entry end |
#exit_code ⇒ Object
Exit code.
45 46 47 |
# File 'lib/tapout/reporters/abstract.rb', line 45 def exit_code @exit_code end |
#fail(entry) ⇒ Object
Handle test with fail status.
110 111 112 |
# File 'lib/tapout/reporters/abstract.rb', line 110 def fail(entry) @failed << entry end |
#finish_case(entry) ⇒ Object
When a test case is complete.
130 131 |
# File 'lib/tapout/reporters/abstract.rb', line 130 def finish_case(entry) end |
#finish_suite(entry) ⇒ Object
Handle footer.
134 135 |
# File 'lib/tapout/reporters/abstract.rb', line 134 def finish_suite(entry) end |
#handle(entry) ⇒ Object
Handler method. This dispatches a given entry to the appropriate report methods.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/tapout/reporters/abstract.rb', line 56 def handle(entry) case entry['type'] when 'suite' start_suite(entry) when 'case' finish_case(@previous_case) if @previous_case @previous_case = entry start_case(entry) when 'note' note(entry) when 'test' test(entry) case entry['status'] when 'pass' pass(entry) when 'fail' @exit_code = -1 fail(entry) when 'error' @exit_code = -1 err(entry) when 'omit' omit(entry) when 'todo', 'skip', 'pending' skip(entry) end when 'tally' finish_case(@previous_case) if @previous_case finish_suite(entry) end end |
#note(entry) ⇒ Object
Handle an arbitray note.
97 98 |
# File 'lib/tapout/reporters/abstract.rb', line 97 def note(entry) end |
#omit(entry) ⇒ Object
Handle test with omit status.
120 121 122 |
# File 'lib/tapout/reporters/abstract.rb', line 120 def omit(entry) @omitted << entry end |
#parse_source_location(caller) ⇒ Object
Parse source location from caller, caller or an Exception object.
260 261 262 263 264 265 266 267 268 269 270 271 |
# File 'lib/tapout/reporters/abstract.rb', line 260 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 returnf source_file, source_line end |
#pass(entry) ⇒ Object
Handle test with pass status.
105 106 107 |
# File 'lib/tapout/reporters/abstract.rb', line 105 def pass(entry) @passed << entry end |
#skip(entry) ⇒ Object
Handle test with skip or pending status.
125 126 127 |
# File 'lib/tapout/reporters/abstract.rb', line 125 def skip(entry) @skipped << entry end |
#source(file) ⇒ Object
Cache source file text. This is only used if the TAP-Y stream doesn not provide a snippet and the test file is locatable.
253 254 255 256 257 |
# File 'lib/tapout/reporters/abstract.rb', line 253 def source(file) @source[file] ||= ( File.readlines(file) ) end |
#start_case(entry) ⇒ Object
At the start of a new test case.
93 94 |
# File 'lib/tapout/reporters/abstract.rb', line 93 def start_case(entry) end |
#start_suite(entry) ⇒ Object
Handle header.
89 90 |
# File 'lib/tapout/reporters/abstract.rb', line 89 def start_suite(entry) end |
#tally(entry) ⇒ Object
TODO: get the tally’s from the footer entry ?
138 139 140 141 142 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 |
# File 'lib/tapout/reporters/abstract.rb', line 138 def tally(entry) total = @passed.size + @failed.size + @raised.size #+ @skipped.size + @omitted.size if entry['counts'] total = entry['counts']['total'] || total count_fail = entry['counts']['fail'] || 0 count_error = entry['counts']['error'] || 0 else count_fail = @failed.size count_error = @raised.size end if tally = entry['counts'] sums = %w{pass fail error todo omit}.map{ |e| tally[e] || 0 } else sums = [@passed, @failed, @raised, @skipped, @omitted].map{ |e| e.size } end # ??? assertions = entry['assertions'] failures = entry['failures'] if assertions text = "%s tests: %s pass, %s fail, %s err, %s todo, %omit (%s/%s assertions)" text = text % [total, *sums] + [assertions - failures, assertions] else text = "%s tests: %s pass, %s fail, %s err, %s todo, %s omit" text = text % [total, *sums] end if count_fail > 0 text.ansi(:red) elsif count_error > 0 text.ansi(:yellow) else text.ansi(:green) end end |
#test(entry) ⇒ Object
Handle test. This is run before the status handlers.
101 102 |
# File 'lib/tapout/reporters/abstract.rb', line 101 def test(entry) end |