class QED::Reporter::Abstract
Reporter
Absract Base Class¶ ↑
Serves as the base class for all other output formats.
Constants
- DEFAULT_TRACE_COUNT
Default trace count. This is the number of backtrace lines that will be provided on errors and failed assertions, unless otherwise overridden with ENV.
- INFO_SIGNAL
Does the system support INFO signal?
- INTERNALS
TODO: Use global standard for backtrace exclusions.
Attributes
Public Class Methods
# File lib/qed/reporter/abstract.rb, line 89 def self.After(type, &block) # raise ArgumentError unless %w{session demo demonstration step pass fail error}.include?(type.to_s) # type = :demonstration if type.to_s == 'demo' define_method("after_#{type}", &block) end
# File lib/qed/reporter/abstract.rb, line 83 def self.Before(type, &block) # raise ArgumentError unless %w{session demo demonstration step}.include?(type.to_s) # type = :demonstration if type.to_s == 'demo' define_method("before_#{type}", &block) end
# File lib/qed/reporter/abstract.rb, line 77 def self.When(type, &block) #raise ArgumentError unless %w{session demo demonstration step}.include?(type.to_s) #type = :demonstration if type.to_s == 'demo' define_method(type, &block) end
TODO: pass session into initialize
# File lib/qed/reporter/abstract.rb, line 31 def initialize(options={}) @io = options[:io] || STDOUT @trace = options[:trace] @record = { :demo => [], :step => [], :omit => [], :pass => [], :fail => [], :error => [] } #@demos = 0 #@steps = 0 #@omit = [] #@pass = [] #@fail = [] #@error = [] @source = {} end
Public Instance Methods
End of a demonstration.
# File lib/qed/reporter/abstract.rb, line 225 def after_demo(demo) #demo(demo) end
# File lib/qed/reporter/abstract.rb, line 213 def after_eval(step) end
# File lib/qed/reporter/abstract.rb, line 209 def after_import(file) end
# File lib/qed/reporter/abstract.rb, line 217 def after_proc(step) end
After
running all demonstrations. This is the place to output a summary of the session, if applicable.
# File lib/qed/reporter/abstract.rb, line 230 def after_session(session) end
# File lib/qed/reporter/abstract.rb, line 221 def after_step(step) end
Beginning of a demonstration.
# File lib/qed/reporter/abstract.rb, line 139 def before_demo(demo) #demo(demo) #demos << demo end
# File lib/qed/reporter/abstract.rb, line 156 def before_eval(step) end
# File lib/qed/reporter/abstract.rb, line 144 def before_import(file) end
# File lib/qed/reporter/abstract.rb, line 152 def before_proc(step) end
At the start of a session, before running any demonstrations.
# File lib/qed/reporter/abstract.rb, line 133 def before_session(session) @session = session @start_time = Time.now end
# File lib/qed/reporter/abstract.rb, line 148 def before_step(step) end
# File lib/qed/reporter/abstract.rb, line 72 def call(type, *args) __send__("count_#{type}", *args) if respond_to?("count_#{type}") __send__(type, *args) if respond_to?(type) end
def After(type, target, *args)
type = :demonstration if type.to_s == 'demo' __send__("after_#{type}", target, *args)
end
# File lib/qed/reporter/abstract.rb, line 107 def count_demo(demo) @record[:demo] << demo end
# File lib/qed/reporter/abstract.rb, line 127 def count_error(step, exception) @record[:error] << [step, exception] end
# File lib/qed/reporter/abstract.rb, line 123 def count_fail(step, exception) @record[:fail] << [step, exception] end
def count_eval(step)
@record[:eval] << step
end
# File lib/qed/reporter/abstract.rb, line 119 def count_pass(step) @record[:pass] << step end
# File lib/qed/reporter/abstract.rb, line 111 def count_step(step) @record[:step] << step end
Reight before demo.
# File lib/qed/reporter/abstract.rb, line 165 def demo(demo) end
# File lib/qed/reporter/abstract.rb, line 54 def demos ; @record[:demo] ; end
After
running a step that raised an error.
# File lib/qed/reporter/abstract.rb, line 203 def error(step, exception) raise exception if $DEBUG # TODO: do we really want to do it like this? ## @error << [step, exception] end
# File lib/qed/reporter/abstract.rb, line 58 def errors ; @record[:error] ; end
Right before evaluation.
# File lib/qed/reporter/abstract.rb, line 185 def eval(step) end
After
running a step that failed.
# File lib/qed/reporter/abstract.rb, line 198 def fail(step, assertion) ## @fail << [step, assertion] end
# File lib/qed/reporter/abstract.rb, line 59 def fails ; @record[:fail] ; end
Right before import.
# File lib/qed/reporter/abstract.rb, line 169 def import(file) end
# File lib/qed/reporter/abstract.rb, line 56 def omits ; @record[:omit] ; end
After
running a step that passed.
# File lib/qed/reporter/abstract.rb, line 193 def pass(step) #@pass << step end
# File lib/qed/reporter/abstract.rb, line 57 def passes ; @record[:pass] ; end
Right before evaluation.
# File lib/qed/reporter/abstract.rb, line 181 def proc(step) end
Right before rule section.
# File lib/qed/reporter/abstract.rb, line 173 def rule(step) end
Right before text section.
# File lib/qed/reporter/abstract.rb, line 177 def step(step) #show text ? end
# File lib/qed/reporter/abstract.rb, line 55 def steps ; @record[:step] ; end
# File lib/qed/reporter/abstract.rb, line 67 def success? record[:error].size + record[:fail].size == 0 end
# File lib/qed/reporter/abstract.rb, line 62 def trace? @trace end
Private Instance Methods
# File lib/qed/reporter/abstract.rb, line 274 def clean_backtrace(*btrace) stack = if $DEBUG btrace else btrace.reject{ |bt| bt =~ INTERNALS } end stack.map do |bt| bt.chomp(":in \`__binding__'") end end
Produce a pretty code snippet given an exception.
@param exception [Exception, String]
An exception or backtrace.
@param radius [Integer]
The number of surrounding lines to show.
@return [String] pretty code snippet
# File lib/qed/reporter/abstract.rb, line 308 def code_snippet(exception, radius=2) radius = radius.to_i file, lineno = file_and_line(exception) return nil if file.empty? return nil if file == '(eval)' source = source(file) region = [lineno - radius, 1].max .. [lineno + radius, source.length].min # ensure proper alignment by zero-padding line numbers format = " %2s %0#{region.last.to_s.length}d %s" pretty = region.map do |n| format % [('=>' if n == lineno), n, source[n-1].chomp] end #.unshift "[#{region.inspect}] in #{source_file}" pretty end
@param exception [Exception,Array,String]
An exception or backtrace.
# File lib/qed/reporter/abstract.rb, line 379 def file_and_line(exception) backtrace = case exception when Exception exception.backtrace.reject{ |bt| bt =~ INTERNALS }.first when Array exception.first else exception end backtrace =~ /(.+?):(\d+(?=:|\z))/ or return "" file, lineno = $1, $2.to_i return file, lineno #i = backtrace.rindex(':in') #line = i ? line[0...i] : line #relative_file(line) end
Same as file_and_line
, exception return file path is relative.
# File lib/qed/reporter/abstract.rb, line 401 def file_line(exception) file, lineno = file_and_line(exception) return relative_file(file), lineno end
# File lib/qed/reporter/abstract.rb, line 251 def get_tally assert_count = $ASSERTION_COUNTS[:total] assert_fails = $ASSERTION_COUNTS[:fail] assert_delta = assert_count - assert_fails vars = [demos.size, steps.size, fails.size, errors.size, assert_delta, assert_count] #, @pass.size ] vars end
# File lib/qed/reporter/abstract.rb, line 441 def localize_file(file) j = 0 [file.to_s.size, Dir.pwd.size].max.times do |i| if Dir.pwd[i,1] != file[i,1] break j = i end end file[j..-1] end
# File lib/qed/reporter/abstract.rb, line 239 def print_tally #assert_count = AE::Assertor.counts[:total] #assert_fails = AE::Assertor.counts[:fail] #assert_delta = assert_count - assert_fails mask = "%s demos, %s steps: %s failures, %s errors (%s/%s assertions)" #vars = [demos.size, steps.size, fails.size, errors.size, assert_delta, assert_count] #, @pass.size ] io.puts mask % get_tally end
# File lib/qed/reporter/abstract.rb, line 235 def print_time io.puts "\nFinished in %.5f seconds.\n\n" % [Time.now - @start_time] end
# File lib/qed/reporter/abstract.rb, line 431 def relative_file(file) pwd = Dir.pwd idx = (0...pwd.size).find do |i| file[i,1] != pwd[i,1] end idx ||= 1 file[(idx-1)..-1] end
# File lib/qed/reporter/abstract.rb, line 265 def sane_backtrace(exception) if trace_count clean_backtrace(*exception.backtrace[0, trace_count]) else clean_backtrace(*exception.backtrace) end end
Cache the source code of a file.
@param file [String] full pathname to file
@return [String] source code
# File lib/qed/reporter/abstract.rb, line 363 def source(file) @source[file] ||= ( if File.exist?(file) File.readlines(file) else '' end ) end
Return a structure code snippet in an array of lineno=>line hash elements.
@param exception [Exception, String]
An exception or backtrace.
@param radius [Integer]
The number of surrounding lines to show.
@return [Hash] structured code snippet
# File lib/qed/reporter/abstract.rb, line 341 def structured_code_snippet(exception, radius=2) radius = radius.to_i file, lineno = file_and_line(exception) return {} if file.empty? source = source(file) region = [lineno - radius, 1].max .. [lineno + radius, source.length].min region.map do |n| {n => source[n-1].chomp} end end
Looks at ENV to determine how much trace output to provide. If it is not set, or set to`false` or ‘off`, then the default trace count is used. If set to `0`, `true`, ’on’ or ‘all’ then aa complete trace dump is provided. Otherwise the value is converted to an integer and that many line of trace is given.
@return [Integer, nil] trace count
# File lib/qed/reporter/abstract.rb, line 418 def trace_count cnt = ENV['trace'] case cnt when nil, 'false', 'off' DEFAULT_TRACE_COUNT when 0, 'all', 'true', 'on' nil else Integer(cnt) end end