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

io[R]
record[R]
session[R]

Public Class Methods

After(type, &block) click to toggle source
# 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
Before(type, &block) click to toggle source
# 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
When(type, &block) click to toggle source
# 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
new(options={}) click to toggle source

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

after_demo(demo) click to toggle source

End of a demonstration.

# File lib/qed/reporter/abstract.rb, line 225
def after_demo(demo)  #demo(demo)
end
after_eval(step) click to toggle source
# File lib/qed/reporter/abstract.rb, line 213
def after_eval(step)
end
after_import(file) click to toggle source
# File lib/qed/reporter/abstract.rb, line 209
def after_import(file)
end
after_proc(step) click to toggle source
# File lib/qed/reporter/abstract.rb, line 217
def after_proc(step)
end
after_session(session) click to toggle source

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
after_step(step) click to toggle source
# File lib/qed/reporter/abstract.rb, line 221
def after_step(step)
end
before_demo(demo) click to toggle source

Beginning of a demonstration.

# File lib/qed/reporter/abstract.rb, line 139
def before_demo(demo) #demo(demo)
  #demos << demo
end
before_eval(step) click to toggle source
# File lib/qed/reporter/abstract.rb, line 156
def before_eval(step)
end
before_import(file) click to toggle source
# File lib/qed/reporter/abstract.rb, line 144
def before_import(file)
end
before_proc(step) click to toggle source
# File lib/qed/reporter/abstract.rb, line 152
def before_proc(step)
end
before_session(session) click to toggle source

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
before_step(step) click to toggle source
# File lib/qed/reporter/abstract.rb, line 148
def before_step(step)
end
call(type, *args) click to toggle source
# 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
count_demo(demo) click to toggle source

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
count_error(step, exception) click to toggle source
# File lib/qed/reporter/abstract.rb, line 127
def count_error(step, exception)
  @record[:error] << [step, exception]
end
count_fail(step, exception) click to toggle source
# File lib/qed/reporter/abstract.rb, line 123
def count_fail(step, exception)
  @record[:fail] << [step, exception]
end
count_pass(step) click to toggle source

def count_eval(step)

@record[:eval] << step

end

# File lib/qed/reporter/abstract.rb, line 119
def count_pass(step)
  @record[:pass] << step
end
count_step(step) click to toggle source
# File lib/qed/reporter/abstract.rb, line 111
def count_step(step)
  @record[:step] << step
end
demo(demo) click to toggle source

Reight before demo.

# File lib/qed/reporter/abstract.rb, line 165
def demo(demo)
end
demos() click to toggle source
# File lib/qed/reporter/abstract.rb, line 54
def demos  ; @record[:demo]  ; end
error(step, exception) click to toggle source

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
errors() click to toggle source
# File lib/qed/reporter/abstract.rb, line 58
def errors ; @record[:error] ; end
eval(step) click to toggle source

Right before evaluation.

# File lib/qed/reporter/abstract.rb, line 185
def eval(step)
end
fail(step, assertion) click to toggle source

After running a step that failed.

# File lib/qed/reporter/abstract.rb, line 198
def fail(step, assertion)
  ## @fail << [step, assertion]
end
fails() click to toggle source
# File lib/qed/reporter/abstract.rb, line 59
def fails  ; @record[:fail]  ; end
import(file) click to toggle source

Right before import.

# File lib/qed/reporter/abstract.rb, line 169
def import(file)
end
omits() click to toggle source
# File lib/qed/reporter/abstract.rb, line 56
def omits  ; @record[:omit]  ; end
pass(step) click to toggle source

After running a step that passed.

# File lib/qed/reporter/abstract.rb, line 193
def pass(step)
  #@pass << step
end
passes() click to toggle source
# File lib/qed/reporter/abstract.rb, line 57
def passes ; @record[:pass]  ; end
proc(step) click to toggle source

Right before evaluation.

# File lib/qed/reporter/abstract.rb, line 181
def proc(step)
end
rule(step) click to toggle source

Right before rule section.

# File lib/qed/reporter/abstract.rb, line 173
def rule(step)
end
step(step) click to toggle source

Right before text section.

# File lib/qed/reporter/abstract.rb, line 177
def step(step)  #show text ?
end
steps() click to toggle source
# File lib/qed/reporter/abstract.rb, line 55
def steps  ; @record[:step]  ; end
success?() click to toggle source
# File lib/qed/reporter/abstract.rb, line 67
def success?
  record[:error].size + record[:fail].size == 0
end
trace?() click to toggle source
# File lib/qed/reporter/abstract.rb, line 62
def trace?
  @trace
end

Private Instance Methods

clean_backtrace(*btrace) click to toggle source
# 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
code_snippet(exception, radius=2) click to toggle source

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
file_and_line(exception) click to toggle source

@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
file_line(exception) click to toggle source

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
get_tally() click to toggle source
# 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
localize_file(file) click to toggle source
# 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
print_tally() click to toggle source
print_time() click to toggle source
relative_file(file) click to toggle source
# 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
sane_backtrace(exception) click to toggle source
# 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
source(file) click to toggle source

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
structured_code_snippet(exception, radius=2) click to toggle source

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
trace_count() click to toggle source

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