module Riot class Reporter attr_accessor :passes, :failures, :errors, :current_context def initialize @passes = @failures = @errors = 0 @current_context = "" end def new(*args, &block); self; end def success?; (@failures + @errors) == 0; end def summarize(&block) started = Time.now yield ensure results(Time.now - started) end def describe_context(context); @current_context = context; end def report(description, response) code, result = *response case code when :pass then @passes += 1 pass(description, result) when :fail then @failures += 1 message, line, file = *response[1..-1] fail(description, message, line, file) when :error then @errors += 1 error(description, result) end end def pass(description, result); end def fail(description, message, line, file); end def error(description, result); end end # Reporter class IOReporter < Reporter def initialize(writer=STDOUT) super() @writer = writer end def puts(message) @writer.puts(message); end def print(message) @writer.print(message); end def line_info(line, file) line ? "(on line #{line} in #{file})" : "" end def results(time_taken) values = [passes, failures, errors, ("%0.6f" % time_taken)] puts "\n%d passes, %d failures, %d errors in %s seconds" % values end def format_error(e) format = [] format << " #{e.class.name} occurred" format << "#{e.to_s}" e.backtrace.each { |line| format << " at #{line}" } format.join("\n") end begin raise LoadError if ENV["TM_MODE"] require 'rubygems' require 'term/ansicolor' include Term::ANSIColor rescue LoadError def green(str); str; end alias :red :green alias :yellow :green end end class StoryReporter < IOReporter def describe_context(context) super puts context.detailed_description end def pass(description, message) puts " + " + green("#{description} #{message}".strip); end def fail(description, message, line, file) puts " - " + yellow("#{description}: #{message} #{line_info(line, file)}".strip) end def error(description, e) puts " ! " + red("#{description}: #{e.message}"); end end class VerboseStoryReporter < StoryReporter def error(description, e) super puts red(format_error(e)) end end class DotMatrixReporter < IOReporter def initialize(writer=STDOUT) super @details = [] end def pass(description, message) print green(".") end def fail(description, message, line, file) print yellow("F") @details << "FAILURE - #{test_detail(description, message)} #{line_info(line, file)}".strip end def error(description, e) print red("E") @details << "ERROR - #{test_detail(description, format_error(e))}" end def results(time_taken) puts "\n#{@details.join("\n\n")}" unless @details.empty? super end private def test_detail(description, message) "#{current_context.detailed_description} #{description} => #{message}" end end class SilentReporter < Reporter def pass(description, message); end def fail(description, message, line, file); end def error(description, e); end def results(time_taken); end end end # Riot