redgreen-expectations.rb

割とMonkey Patchingしちゃってるので将来が不安。
所詮へぼハックの産物よ。

とりあえずWinXPでしか動作確認してないです。

2008/06/13追記:
Winじゃなくても結局win32consoleに依存してたのを修正。

#
# RedGreen for expectations - version 0.1.0
#  (c) arikui <arikui.ruby@gmail.com>
#
# Last modified: 2008/06/13 14:57:13;
#

require 'expectations'
require 'rubygems'
begin
  require 'win32ole'
rescue LoadError
  ;
else
  require 'win32console'
end

module Expectations
  
  class Suite
    
    #
    # re-define `execute'
    #
    meth = instance_method(:execute)
    define_method(:execute) do |*args|
      args.unshift($stdout) if args.empty?
      meth.bind(self).call(*args)
    end
    
  end #class Suite
  
  class SuiteResults
    
    #
    # re-define `initialize'
    #
    meth = instance_method(:initialize)
    define_method(:initialize) do |out|
      meth.bind(self).call ColoringPort.new(out)
    end
    
    class ColoringPort
      
      def initialize(out)
        @out = out
        @out << clear
      end
      
      def print(*args)
        @out.print *args.map{|s| filter s }
      end
      
      def puts(*args)
        @out.puts *args.map{|s| filter s }
      end
      
      private
      
      def filter(str)
        case str
        when /\A\.\Z/             then on_green('.')
        when /\AE\Z/              then on_yellow('E')
        when /\AF\Z/              then on_red('F')
        when /\A\nSuccess/        then filter_success_counts($')
        when /\A\nFailure/        then filter_failure_counts($')
        when /\A\n--Errors--\Z/   then on_yellow(str)
        when /\A\n--Failures--\Z/ then on_red(str)
        else str
        end
      end
      
      def filter_success_counts(str)
        "\n#{on_green('Success')}#{str.sub(/\d+/){|m| green(m) }}"
      end
      
      FAILURE_COUNTS_SEQ = [
        [ :red,    "failed"    ],
        [ :green,  "errors"    ],
        [ :yellow, "fulfilled" ],
      ]
      
      def filter_failure_counts(str)
        tmp = str.scan(/\d+/).zip(FAILURE_COUNTS_SEQ).map{|v, (c, mes)|
          "#{__send__(c, v)} #{mes}"
        }.join(', ')
        "\n#{on_red('Failure')}: #{tmp}"
      end
      
      ColorTable = {
        :red        => 31,
        :green      => 32,
        :yellow     => 33,
        :on_red     => 41,
        :on_green   => 42,
        :on_yellow  => 43,
      }
      
      def col_seq(v)
        "\e[#{v}m"
      end
      
      def clear
        col_seq 0
      end
      
      ColorTable.each do |name, v|
        define_method(name){|s| "#{col_seq(v)}#{s}#{clear}" }
      end
      
    end #class ColoringPort
    
  end #class SuiteResults
  
end #module Expectations