class Test::Unit::UI::Tap::BaseTestRunner
Base class for all TAP runners.
Constants
- REVISION
TAP-Y/J Revision
Public Class Methods
new(suite, options={})
click to toggle source
Calls superclass method
# File lib/test/unit/ui/tap/base_testrunner.rb, line 18 def initialize(suite, options={}) super @output = @options[:output] || STDOUT @level = 0 @_source_cache = {} @already_outputted = false @top_level = true @counts = Hash.new{ |h,k| h[k] = 0 } end
Private Instance Methods
attach_to_mediator()
click to toggle source
# File lib/test/unit/ui/tap/base_testrunner.rb, line 45 def attach_to_mediator @mediator.add_listener(Test::Unit::TestResult::FAULT, &method(:tapout_fault)) @mediator.add_listener(Test::Unit::UI::TestRunnerMediator::STARTED, &method(:tapout_before_suite)) @mediator.add_listener(Test::Unit::UI::TestRunnerMediator::FINISHED, &method(:tapout_after_suite)) @mediator.add_listener(Test::Unit::TestCase::STARTED_OBJECT, &method(:tapout_before_test)) @mediator.add_listener(Test::Unit::TestCase::FINISHED_OBJECT, &method(:tapout_pass)) @mediator.add_listener(Test::Unit::TestSuite::STARTED_OBJECT, &method(:tapout_before_case)) @mediator.add_listener(Test::Unit::TestSuite::FINISHED_OBJECT, &method(:tapout_after_case)) end
captured_output()
click to toggle source
# File lib/test/unit/ui/tap/base_testrunner.rb, line 476 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
clean_label(name)
click to toggle source
# File lib/test/unit/ui/tap/base_testrunner.rb, line 342 def clean_label(name) name.sub(/\(.+?\)\z/, '').chomp('()') end
clean_message(message)
click to toggle source
# File lib/test/unit/ui/tap/base_testrunner.rb, line 453 def clean_message(message) message.strip.gsub(/\n+/, "\n") end
code_snippet(file, line)
click to toggle source
Returns a Hash of source code.
# File lib/test/unit/ui/tap/base_testrunner.rb, line 373 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
code_snippet_array(file, line)
click to toggle source
Return Array of source code line numbers and text.
# File lib/test/unit/ui/tap/base_testrunner.rb, line 404 def code_snippet_array(file, line) snp = [] 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 snp = region.map do |n| [n, source[n-1].chomp] end end return snp end
code_snippet_string(file, line)
click to toggle source
Return nicely formated String of code lines.
# File lib/test/unit/ui/tap/base_testrunner.rb, line 389 def code_snippet_string(file, line) str = [] snp = code_snippet_array(file, line) max = snp.map{ |n, c| n.to_s.size }.max snp.each do |n, c| if n == line str << "=> %#{max}d %s" % [n, c] else str << " %#{max}d %s" % [n, c] end end str.join("\n") end
filter_backtrace(backtrace)
click to toggle source
Clean the backtrace of any reference to test framework itself.
# File lib/test/unit/ui/tap/base_testrunner.rb, line 347 def filter_backtrace(backtrace) trace = backtrace ## remove backtraces that match any pattern in $RUBY_IGNORE_CALLERS #trace = race.reject{|b| $RUBY_IGNORE_CALLERS.any?{|i| i=~b}} ## remove `:in ...` portion of backtraces trace = trace.map do |bt| i = bt.index(':in') i ? bt[0...i] : bt end # TODO: does TestUnit have a filter ? ## now apply MiniTest's own filter (note: doesn't work if done first, why?) #trace = MiniTest::filter_backtrace(trace) ## if the backtrace is empty now then revert to the original trace = backtrace if trace.empty? ## simplify paths to be relative to current workding diectory trace = trace.map{ |bt| bt.sub(Dir.pwd+File::SEPARATOR,'') } return trace end
location(backtrace)
click to toggle source
Get location of exception.
# File lib/test/unit/ui/tap/base_testrunner.rb, line 441 def location(backtrace) last_before_assertion = "" backtrace.reverse_each do |s| break if s =~ /in .(assert|refute|flunk|pass|fail|raise|must|wont)/ last_before_assertion = s end file, line = last_before_assertion.sub(/:in .*$/, '').split(':') line = line.to_i if line return file, line end
parse_source_location(caller)
click to toggle source
Parse source location from caller, caller or an Exception object.
# File lib/test/unit/ui/tap/base_testrunner.rb, line 427 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
puts(string='')
click to toggle source
# File lib/test/unit/ui/tap/base_testrunner.rb, line 458 def puts(string='') @output.write(string.chomp+"\n") @output.flush end
reset_output()
click to toggle source
# File lib/test/unit/ui/tap/base_testrunner.rb, line 464 def reset_output @_oldout = $stdout @_olderr = $stderr @_newout = StringIO.new @_newerr = StringIO.new $stdout = @_newout $stderr = @_newerr end
setup_mediator()
click to toggle source
Calls superclass method
# File lib/test/unit/ui/tap/base_testrunner.rb, line 35 def setup_mediator super #suite_name = @suite.to_s # file name #suite_name = @suite.name if @suite.kind_of?(Module) #reset_output # TODO: Should we do this up front? end
source(file)
click to toggle source
Cache source file text. This is only used if the TAP-Y stream doesn not provide a snippet and the test file is locatable.
# File lib/test/unit/ui/tap/base_testrunner.rb, line 420 def source(file) @_source_cache[file] ||= ( File.readlines(file) ) end
tapout_after_case(testcase)
click to toggle source
After each case, decrement the case level.
# File lib/test/unit/ui/tap/base_testrunner.rb, line 119 def tapout_after_case(testcase) @level -= 1 end
tapout_after_suite(elapsed_time)
click to toggle source
After everything else.
# File lib/test/unit/ui/tap/base_testrunner.rb, line 75 def tapout_after_suite(elapsed_time) doc = { 'type' => 'final', 'time' => elapsed_time, #Time.now - @suite_start, 'counts' => { 'total' => @counts[:total], 'pass' => @counts[:pass], #self.test_count - self.failures - self.errors - self.skips, 'fail' => @counts[:fail], 'error' => @counts[:error], 'omit' => @counts[:omit], 'todo' => @counts[:todo], } #, #'assertions' => { # 'total' => @result.assertion_count + @counts[:fail], # 'pass' => @result.assertion_count, # 'fail' => @counts[:fail] #} } return doc end
tapout_before_case(testcase)
click to toggle source
# File lib/test/unit/ui/tap/base_testrunner.rb, line 99 def tapout_before_case(testcase) return nil if testcase.test_case.nil? @test_case = testcase doc = { 'type' => 'case', #'subtype' => '', 'label' => testcase.name, 'level' => @level } @level += 1 return doc end
tapout_before_suite(result)
click to toggle source
Before everything else.
# File lib/test/unit/ui/tap/base_testrunner.rb, line 58 def tapout_before_suite(result) @result = result @suite_start = Time.now doc = { 'type' => 'suite', 'start' => @suite_start.strftime('%Y-%m-%d %H:%M:%S'), 'count' => @suite.size, #'seed' => #@suite.seed, # no seed? 'rev' => REVISION } return doc end
tapout_before_test(test)
click to toggle source
# File lib/test/unit/ui/tap/base_testrunner.rb, line 124 def tapout_before_test(test) @test_start = Time.now # set up stdout and stderr to be captured reset_output end
tapout_error(fault)
click to toggle source
# File lib/test/unit/ui/tap/base_testrunner.rb, line 302 def tapout_error(fault) @counts[:total] += 1 @counts[:error] += 1 file, line = location(fault.location) rel_file = file.sub(Dir.pwd+'/', '') doc = { 'type' => 'test', #'subtype' => '', 'status' => 'error', 'label' => clean_label(fault.test_name), #'setup' => "foo instance", #'expected' => fault.inspected_expected, #'returned' => fault.inspected_actual, #'file' => test_file #'line' => test_line #'source' => ok 1, 2 #'snippet' => # - 44: ok 0,0 # - 45: ok 1,2 # - 46: ok 2,4 'exception' => { 'message' => clean_message(fault.message), 'class' => fault.class.name, 'file' => rel_file, 'line' => line, 'source' => source(file)[line-1].strip, 'snippet' => code_snippet(file, line), 'backtrace' => filter_backtrace(fault.location) }, 'time' => Time.now - @suite_start } doc.update(captured_output) return doc end
tapout_fail(fault)
click to toggle source
# File lib/test/unit/ui/tap/base_testrunner.rb, line 262 def tapout_fail(fault) @counts[:total] += 1 @counts[:fail] += 1 file, line = location(fault.location) rel_file = file.sub(Dir.pwd+'/', '') doc = { 'type' => 'test', #'subtype' => '', 'status' => 'fail', 'label' => clean_label(fault.test_name), #'setup' => "foo instance", 'expected' => fault.inspected_expected, 'returned' => fault.inspected_actual, #'file' => test_file #'line' => test_line #'source' => ok 1, 2 #'snippet' => # - 44: ok 0,0 # - 45: ok 1,2 # - 46: ok 2,4 'exception' => { 'message' => clean_message(fault.user_message || fault.message), 'class' => fault.class.name, 'file' => rel_file, 'line' => line, 'source' => source(file)[line-1].strip, 'snippet' => code_snippet(file, line), 'backtrace' => filter_backtrace(fault.location) }, 'time' => Time.now - @suite_start } doc.update(captured_output) return doc end
tapout_fault(fault)
click to toggle source
# File lib/test/unit/ui/tap/base_testrunner.rb, line 131 def tapout_fault(fault) case fault when Test::Unit::Pending tapout_todo(fault) when Test::Unit::Omission tapout_omit(fault) when Test::Unit::Notification tapout_note(fault) when Test::Unit::Failure tapout_fail(fault) else tapout_error(fault) end @already_outputted = true #if fault.critical? end
tapout_note(note)
click to toggle source
# File lib/test/unit/ui/tap/base_testrunner.rb, line 149 def tapout_note(note) doc = { 'type' => 'note', 'text' => note.message } return doc end
tapout_omit(fault)
click to toggle source
# File lib/test/unit/ui/tap/base_testrunner.rb, line 225 def tapout_omit(fault) @counts[:total] += 1 @counts[:omit] += 1 file, line = location(fault.location) rel_file = file.sub(Dir.pwd+'/', '') doc = { 'type' => 'test', #'subtype' => '', 'status' => 'skip', 'label' => clean_label(fault.test_name), #'setup' => "foo instance", #'expected' => 2, #'returned' => 1, #'file' => test_file #'line' => test_line #'source' => source(test_file)[test_line-1].strip, #'snippet' => code_snippet(test_file, test_line), 'exception' => { 'message' => clean_message(fault.message), 'class' => fault.class.name, 'file' => rel_file, 'line' => line, 'source' => source(file)[line-1].strip, 'snippet' => code_snippet(file, line), 'backtrace' => filter_backtrace(fault.location) }, 'time' => Time.now - @suite_start } doc.update(captured_output) return doc end
tapout_pass(test)
click to toggle source
# File lib/test/unit/ui/tap/base_testrunner.rb, line 158 def tapout_pass(test) if @already_outputted @already_outputted = false return nil end @counts[:total] += 1 @counts[:pass] += 1 doc = { 'type' => 'test', #'subtype' => '', 'status' => 'pass', #'setup': foo instance 'label' => clean_label(test.name), #'expected' => 2 #'returned' => 2 #'file' => test_file #'line' => test_line #'source' => source(test_file)[test_line-1].strip, #'snippet' => code_snippet(test_file, test_line), 'time' => Time.now - @suite_start } doc.update(captured_output) return doc end
tapout_todo(fault)
click to toggle source
# File lib/test/unit/ui/tap/base_testrunner.rb, line 188 def tapout_todo(fault) @counts[:total] += 1 @counts[:todo] += 1 file, line = location(fault.location) rel_file = file.sub(Dir.pwd+'/', '') doc = { 'type' => 'test', #'subtype' => '', 'status' => 'todo', 'label' => clean_label(fault.test_name), #'setup' => "foo instance", #'expected' => 2, #'returned' => 1, #'file' => test_file #'line' => test_line #'source' => source(test_file)[test_line-1].strip, #'snippet' => code_snippet(test_file, test_line), 'exception' => { 'message' => clean_message(fault.message), 'class' => fault.class.name, 'file' => rel_file, 'line' => line, 'source' => source(file)[line-1].strip, 'snippet' => code_snippet(file, line), 'backtrace' => filter_backtrace(fault.location) }, 'time' => Time.now - @suite_start } doc.update(captured_output) return doc end