beginrequire"spec/runner/formatter/base_text_formatter"rescueLoadErrorrequire"rspec/core/formatters/base_text_formatter"endrequire"rubygems"require"rtui"moduleRspecSpinnerclassRspecSpinnerBase<RSpec::Core::Formatters::BaseTextFormatter# Threshold for slow specs, in seconds.# Anything that takes longer than this will be printed out#THRESHOLD = 0.25THRESHOLD=3.0attr_reader:total,:currentdefinitialize(options,where=nil)superoptions@example_times=[]enddefstart(example_count)@current=0@total=example_count@error_state=:all_passing@pbar=RTUI::Progress.new("#{example_count} examples",example_count,{:out=>output,:components=>[:percentage,:spinner,:stat]})enddefexample_started(example)super@start_time=Time.nowenddefexample_passed(example)ex=[example_group.description,example.description,example.location,Time.now-@start_time]print_warning_if_slow(*ex)@example_times<<exincrementend# third param is optional, because earlier versions of rspec sent only two argsdefexample_pending(example,message,deprecated_pending_location=nil)immediately_dump_pending(example.description,message,example.location)mark_error_state_pendingincrementenddefexample_failed(example,counter,failure)immediately_dump_failure(counter,failure)mark_error_state_failedincrementenddefstart_dumpoutput.flushsuper@output.puts"\n\nTop 15 slowest examples:\n"@example_times=@example_times.sort_bydo|description,example,location,time|timeend.reverse@example_times[0..14].eachdo|description,example,location,time|_,line=location.split(":")@output.printred(sprintf("%.7f",time))@output.puts" #{description}:#{line}#{example}"end@output.flushenddefdump_failure(*args)# no-op; we summarized failures as we were runningenddefmethod_missing(sym,*args)# ignoreenddefself.fmt_backtrace(bkt)return""ifbkt.nil?returnbkt.split("\n")end# stolen and slightly modified from BaseTextFormatter#dump_failuredefimmediately_dump_failure(counter,failure)erase_current_lineoutput.putsoutput.print"#{counter.to_s}) "# Rspec 1.2.2output.putscolorize_failure("#{failure.header}\n#{failure.exception.message}",failure)output.putsfailure.exception.backtraceoutput.putsend# stolen and modified from BaseTextFormatter#dump_pendingdefimmediately_dump_pending(desc,msg,location)erase_current_lineoutput.putsyellow("PENDING SPEC:")+" #{desc} (#{msg})"output.puts" Called from #{location}"output.putsenddefincrementwith_colordo@current+=1# HACK: need to make sure the progress is printed, even when the bar hasn't changedif/^1\.8/===RUBY_VERSIONthen@pbar.instance_variable_set("@previous",0)@pbar.instance_variable_set("@title","#{current}/#{total}")else@pbar.instance_variable_set("@previous".to_sym,0)@pbar.instance_variable_set("@title".to_sym,"#{current}/#{total}")end@pbar.incendoutput.flushendERROR_STATE_COLORS={:all_passing=>"\e[32m",# green:some_pending=>"\e[33m",# yellow:some_failed=>"\e[31m",# red:pending_fix=>"\e[34m",# blue}defwith_coloruse_color=colour?&&output_to_tty?output.printERROR_STATE_COLORS[@error_state]ifuse_coloryieldoutput.print"\e[0m"ifuse_colorenddefmark_error_state_failed@error_state=:some_failedenddefmark_error_state_pending@error_state=:some_pendingunless@error_state==:some_failedenddeferase_current_lineoutput.print"\e[K"enddefprint_warning_if_slow(group,example,location,elapsed)ifelapsed>THRESHOLD#mark_error_state(:pending)erase_current_lineoutput.printyellow("SLOW SPEC: #{sprintf("%.4f",elapsed)} ")output.print" FROM: #{location} / #{group}#{example}"output.putsendendendend