[Groonga-commit] groonga/grntest at ab11da9 [master] Extract reporters to lib/grntest/reporters/

Back to archive index

Kouhei Sutou null+****@clear*****
Mon Aug 12 11:39:17 JST 2013


Kouhei Sutou	2013-08-12 11:39:17 +0900 (Mon, 12 Aug 2013)

  New Revision: ab11da910534ef0a62a6c71ff1403a93407619d4
  https://github.com/groonga/grntest/commit/ab11da910534ef0a62a6c71ff1403a93407619d4

  Message:
    Extract reporters to lib/grntest/reporters/

  Added files:
    lib/grntest/reporters.rb
    lib/grntest/reporters/base_reporter.rb
    lib/grntest/reporters/inplace_reporter.rb
    lib/grntest/reporters/mark_reporter.rb
    lib/grntest/reporters/stream_reporter.rb
  Modified files:
    lib/grntest/tester.rb

  Added: lib/grntest/reporters.rb (+35 -0) 100644
===================================================================
--- /dev/null
+++ lib/grntest/reporters.rb    2013-08-12 11:39:17 +0900 (c96c8b4)
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2012-2013  Kouhei Sutou <kou �� clear-code.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+require "grntest/reporters/mark_reporter"
+require "grntest/reporters/stream_reporter"
+require "grntest/reporters/inplace_reporter"
+
+module Grntest
+  module Reporters
+    def create_repoter(tester)
+      case tester.reporter
+      when :mark
+        Reporters::MarkReporter.new(tester)
+      when :stream
+        Reporters::StreamReporter.new(tester)
+      when :inplace
+        Reporters::InplaceReporter.new(tester)
+      end
+    end
+  end
+end

  Added: lib/grntest/reporters/base_reporter.rb (+375 -0) 100644
===================================================================
--- /dev/null
+++ lib/grntest/reporters/base_reporter.rb    2013-08-12 11:39:17 +0900 (399d73d)
@@ -0,0 +1,375 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2012-2013  Kouhei Sutou <kou �� clear-code.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+module Grntest
+  module Reporters
+    class BaseReporter
+      def initialize(tester)
+        @tester = tester
+        @term_width = guess_term_width
+        @output =****@teste*****
+        @mutex = Mutex.new
+        reset_current_column
+      end
+
+      private
+      def synchronize
+        @mutex.synchronize do
+          yield
+        end
+      end
+
+      def report_summary(result)
+        puts(statistics_header)
+        puts(colorize(statistics(result), result))
+        pass_ratio = result.pass_ratio
+        elapsed_time = result.elapsed_time
+        summary = "%.4g%% passed in %.4fs." % [pass_ratio, elapsed_time]
+        puts(colorize(summary, result))
+      end
+
+      def columns
+        [
+          # label,      format value
+          ["tests/sec", lambda {|result| "%9.2f" % throughput(result)}],
+          ["   tests",  lambda {|result| "%8d"   % result.n_tests}],
+          ["  passes",  lambda {|result| "%8d"   % result.n_passed_tests}],
+          ["failures",  lambda {|result| "%8d"   % result.n_failed_tests}],
+          ["  leaked",  lambda {|result| "%8d"   % result.n_leaked_tests}],
+          [" omitted",  lambda {|result| "%8d"   % result.n_omitted_tests}],
+          ["!checked",  lambda {|result| "%8d"   % result.n_not_checked_tests}],
+        ]
+      end
+
+      def statistics_header
+        labels = columns.collect do |label, format_value|
+          label
+        end
+        "  " + labels.join(" | ") + " |"
+      end
+
+      def statistics(result)
+        items = columns.collect do |label, format_value|
+          format_value.call(result)
+        end
+        "  " + items.join(" | ") + " |"
+      end
+
+      def throughput(result)
+        if result.elapsed_time.zero?
+          tests_per_second = 0
+        else
+          tests_per_second = result.n_tests / result.elapsed_time
+        end
+        tests_per_second
+      end
+
+      def report_failure(result)
+        report_marker(result)
+        report_diff(result.expected, result.actual)
+        report_marker(result)
+      end
+
+      def report_actual(result)
+        report_marker(result)
+        puts(result.actual)
+        report_marker(result)
+      end
+
+      def report_marker(result)
+        puts(colorize("=" * @term_width, result))
+      end
+
+      def report_diff(expected, actual)
+        create_temporary_file("expected", expected) do |expected_file|
+          create_temporary_file("actual", actual) do |actual_file|
+            diff_options =****@teste*****_options.dup
+            diff_options.concat(["--label", "(expected)", expected_file.path,
+                                 "--label", "(actual)", actual_file.path])
+            system(@tester.diff, *diff_options)
+          end
+        end
+      end
+
+      def report_test(worker, result)
+        report_marker(result)
+        print("[#{worker.id}] ") if****@teste*****_workers > 1
+        puts(worker.suite_name)
+        print("  #{worker.test_name}")
+        report_test_result(result, worker.status)
+      end
+
+      def report_test_result(result, label)
+        message = test_result_message(result, label)
+        message_width = string_width(message)
+        rest_width = @term_width - @current_column
+        if rest_width > message_width
+          print(" " * (rest_width - message_width))
+        end
+        puts(message)
+      end
+
+      def test_result_message(result, label)
+        elapsed_time = result.elapsed_time
+        formatted_elapsed_time = "%.4fs" % elapsed_time
+        formatted_elapsed_time = colorize(formatted_elapsed_time,
+                                          elapsed_time_status(elapsed_time))
+        " #{formatted_elapsed_time} [#{colorize(label, result)}]"
+      end
+
+      LONG_ELAPSED_TIME = 1.0
+      def long_elapsed_time?(elapsed_time)
+        elapsed_time >= LONG_ELAPSED_TIME
+      end
+
+      def elapsed_time_status(elapsed_time)
+        if long_elapsed_time?(elapsed_time)
+          elapsed_time_status = :failure
+        else
+          elapsed_time_status = :not_checked
+        end
+      end
+
+      def justify(message, width)
+        return " " * width if message.nil?
+        return message.ljust(width) if message.bytesize <= width
+        half_width = width / 2.0
+        elision_mark = "..."
+        left = message[0, half_width.ceil - elision_mark.size]
+        right = message[(message.size - half_width.floor)..-1]
+        "#{left}#{elision_mark}#{right}"
+      end
+
+      def print(message)
+        @current_column += string_width(message.to_s)
+        @output.print(message)
+      end
+
+      def puts(*messages)
+        reset_current_column
+        @output.puts(*messages)
+      end
+
+      def reset_current_column
+        @current_column = 0
+      end
+
+      def create_temporary_file(key, content)
+        file = Tempfile.new("groonga-test-#{key}")
+        file.print(content)
+        file.close
+        yield(file)
+      end
+
+      def guess_term_width
+        Integer(guess_term_width_from_env || guess_term_width_from_stty || 79)
+      rescue ArgumentError
+        0
+      end
+
+      def guess_term_width_from_env
+        ENV["COLUMNS"] || ENV["TERM_WIDTH"]
+      end
+
+      def guess_term_width_from_stty
+        return nil unless STDIN.tty?
+
+        case tty_info
+        when /(\d+) columns/
+          $1
+        when /columns (\d+)/
+          $1
+        else
+          nil
+        end
+      end
+
+      def tty_info
+        begin
+          `stty -a`
+        rescue SystemCallError
+          nil
+        end
+      end
+
+      def string_width(string)
+        string.gsub(/\e\[[0-9;]+m/, "").size
+      end
+
+      def result_status(result)
+        if result.respond_to?(:status)
+          result.status
+        else
+          if result.n_failed_tests > 0
+            :failure
+          elsif result.n_leaked_tests > 0
+            :leaked
+          elsif result.n_omitted_tests > 0
+            :omitted
+          elsif result.n_not_checked_tests > 0
+            :not_checked
+          else
+            :success
+          end
+        end
+      end
+
+      def colorize(message, result_or_status)
+        return message unles****@teste*****_color?
+        if result_or_status.is_a?(Symbol)
+          status = result_or_status
+        else
+          status = result_status(result_or_status)
+        end
+        case status
+        when :success
+          "%s%s%s" % [success_color, message, reset_color]
+        when :failure
+          "%s%s%s" % [failure_color, message, reset_color]
+        when :leaked
+          "%s%s%s" % [leaked_color, message, reset_color]
+        when :omitted
+          "%s%s%s" % [omitted_color, message, reset_color]
+        when :not_checked
+          "%s%s%s" % [not_checked_color, message, reset_color]
+        else
+          message
+        end
+      end
+
+      def success_color
+        escape_sequence({
+                          :color => :green,
+                          :color_256 => [0, 3, 0],
+                          :background => true,
+                        },
+                        {
+                          :color => :white,
+                          :color_256 => [5, 5, 5],
+                          :bold => true,
+                        })
+      end
+
+      def failure_color
+        escape_sequence({
+                          :color => :red,
+                          :color_256 => [3, 0, 0],
+                          :background => true,
+                        },
+                        {
+                          :color => :white,
+                          :color_256 => [5, 5, 5],
+                          :bold => true,
+                        })
+      end
+
+      def leaked_color
+        escape_sequence({
+                          :color => :magenta,
+                          :color_256 => [3, 0, 3],
+                          :background => true,
+                        },
+                        {
+                          :color => :white,
+                          :color_256 => [5, 5, 5],
+                          :bold => true,
+                        })
+      end
+
+      def omitted_color
+        escape_sequence({
+                          :color => :blue,
+                          :color_256 => [0, 0, 1],
+                          :background => true,
+                        },
+                        {
+                          :color => :white,
+                          :color_256 => [5, 5, 5],
+                          :bold => true,
+                        })
+      end
+
+      def not_checked_color
+        escape_sequence({
+                          :color => :cyan,
+                          :color_256 => [0, 1, 1],
+                          :background => true,
+                        },
+                        {
+                          :color => :white,
+                          :color_256 => [5, 5, 5],
+                          :bold => true,
+                        })
+      end
+
+      def reset_color
+        escape_sequence(:reset)
+      end
+
+      COLOR_NAMES = [
+        :black, :red, :green, :yellow,
+        :blue, :magenta, :cyan, :white,
+      ]
+      def escape_sequence(*commands)
+        sequence = []
+        commands.each do |command|
+          case command
+          when :reset
+            sequence << "0"
+          when :bold
+            sequence << "1"
+          when :italic
+            sequence << "3"
+          when :underline
+            sequence << "4"
+          when Hash
+            foreground_p = !command[:background]
+            if available_colors == 256
+              sequence << (foreground_p ? "38" : "48")
+              sequence << "5"
+              sequence << pack_256_color(*command[:color_256])
+            else
+              color_parameter = foreground_p ? 3 : 4
+              color_parameter += 6 if command[:intensity]
+              color = COLOR_NAMES.index(command[:color])
+              sequence << "#{color_parameter}#{color}"
+            end
+          end
+        end
+        "\e[#{sequence.join(';')}m"
+      end
+
+      def pack_256_color(red, green, blue)
+        red * 36 + green * 6 + blue + 16
+      end
+
+      def available_colors
+        case ENV["COLORTERM"]
+        when "gnome-terminal"
+          256
+        else
+          case ENV["TERM"]
+          when /-256color\z/
+            256
+          else
+            8
+          end
+        end
+      end
+    end
+  end
+end

  Added: lib/grntest/reporters/inplace_reporter.rb (+208 -0) 100644
===================================================================
--- /dev/null
+++ lib/grntest/reporters/inplace_reporter.rb    2013-08-12 11:39:17 +0900 (5baa30a)
@@ -0,0 +1,208 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2012-2013  Kouhei Sutou <kou �� clear-code.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+require "grntest/reporters/base_reporter"
+
+module Grntest
+  module Reporters
+    class InplaceReporter < BaseReporter
+      def initialize(tester)
+        super
+        @last_redraw_time = Time.now
+        @minimum_redraw_interval = 0.1
+      end
+
+      def on_start(result)
+        @test_suites_result = result
+      end
+
+      def on_worker_start(worker)
+      end
+
+      def on_suite_start(worker)
+        redraw
+      end
+
+      def on_test_start(worker)
+        redraw
+      end
+
+      def on_test_success(worker, result)
+        redraw
+      end
+
+      def on_test_failure(worker, result)
+        redraw do
+          report_test(worker, result)
+          report_failure(result)
+        end
+      end
+
+      def on_test_leak(worker, result)
+        redraw do
+          report_test(worker, result)
+          report_marker(result)
+          report_actual(result) unless result.checked?
+        end
+      end
+
+      def on_test_omission(worker, result)
+        redraw do
+          report_test(worker, result)
+          report_actual(result)
+        end
+      end
+
+      def on_test_no_check(worker, result)
+        redraw do
+          report_test(worker, result)
+          report_actual(result)
+        end
+      end
+
+      def on_test_finish(worker, result)
+        redraw
+      end
+
+      def on_suite_finish(worker)
+        redraw
+      end
+
+      def on_worker_finish(worker)
+        redraw
+      end
+
+      def on_finish(result)
+        draw
+        puts
+        report_summary(result)
+      end
+
+      private
+      def draw
+        draw_statistics_header_line
+        @test_suites_result.workers.each do |worker|
+          draw_status_line(worker)
+          draw_test_line(worker)
+        end
+        draw_progress_line
+      end
+
+      def draw_statistics_header_line
+        puts(statistics_header)
+      end
+
+      def draw_status_line(worker)
+        clear_line
+        left = "[#{colorize(worker.id, worker.result)}] "
+        right = " [#{worker.status}]"
+        rest_width = @term_width - @current_column
+        center_width = rest_width - string_width(left) - string_width(right)
+        center = justify(worker.suite_name, center_width)
+        puts("#{left}#{center}#{right}")
+      end
+
+      def draw_test_line(worker)
+        clear_line
+        if worker.test_name
+          label = "  #{worker.test_name}"
+        else
+          label = statistics(worker.result)
+        end
+        puts(justify(label, @term_width))
+      end
+
+      def draw_progress_line
+        n_done_tests = @test_suites_result.n_tests
+        n_total_tests = @test_suites_result.n_total_tests
+        if n_total_tests.zero?
+          finished_test_ratio = 0.0
+        else
+          finished_test_ratio = n_done_tests.to_f / n_total_tests
+        end
+
+        start_mark = "|"
+        finish_mark = "|"
+        statistics = " [%3d%%]" % (finished_test_ratio * 100)
+
+        progress_width = @term_width
+        progress_width -= start_mark.bytesize
+        progress_width -= finish_mark.bytesize
+        progress_width -= statistics.bytesize
+        finished_mark = "-"
+        if n_done_tests == n_total_tests
+          progress = colorize(finished_mark * progress_width,
+                              @test_suites_result)
+        else
+          current_mark = ">"
+          finished_marks_width = (progress_width * finished_test_ratio).ceil
+          finished_marks_width -= current_mark.bytesize
+          finished_marks_width = [0, finished_marks_width].max
+          progress = finished_mark * finished_marks_width + current_mark
+          progress = colorize(progress, @test_suites_result)
+          progress << " " * (progress_width - string_width(progress))
+        end
+        puts("#{start_mark}#{progress}#{finish_mark}#{statistics}")
+      end
+
+      def redraw
+        synchronize do
+          unless block_given?
+            return if Time.now - @last_redraw_time < @minimum_redraw_interval
+          end
+          draw
+          if block_given?
+            yield
+          else
+            up_n_lines(n_using_lines)
+          end
+          @last_redraw_time = Time.now
+        end
+      end
+
+      def up_n_lines(n)
+        print("\e[1A" * n)
+      end
+
+      def clear_line
+        print(" " * @term_width)
+        print("\r")
+        reset_current_column
+      end
+
+      def n_using_lines
+        n_statistics_header_line + n_worker_lines * n_workers + n_progress_lines
+      end
+
+      def n_statistics_header_line
+        1
+      end
+
+      def n_worker_lines
+        2
+      end
+
+      def n_progress_lines
+        1
+      end
+
+      def n_workers
+        @tester.n_workers
+      end
+    end
+  end
+end

  Added: lib/grntest/reporters/mark_reporter.rb (+112 -0) 100644
===================================================================
--- /dev/null
+++ lib/grntest/reporters/mark_reporter.rb    2013-08-12 11:39:17 +0900 (c7703ba)
@@ -0,0 +1,112 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2012-2013  Kouhei Sutou <kou �� clear-code.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+require "grntest/reporters/base_reporter"
+
+module Grntest
+  module Reporters
+    class MarkReporter < BaseReporter
+      def initialize(tester)
+        super
+      end
+
+      def on_start(result)
+      end
+
+      def on_worker_start(worker)
+      end
+
+      def on_suite_start(worker)
+      end
+
+      def on_test_start(worker)
+      end
+
+      def on_test_success(worker, result)
+        synchronize do
+          report_test_result_mark(".", result)
+        end
+      end
+
+      def on_test_failure(worker, result)
+        synchronize do
+          report_test_result_mark("F", result)
+          puts
+          report_test(worker, result)
+          report_failure(result)
+        end
+      end
+
+      def on_test_leak(worker, result)
+        synchronize do
+          report_test_result_mark("L(#{result.n_leaked_objects})", result)
+          unless result.checked?
+            puts
+            report_test(worker, result)
+            report_actual(result)
+          end
+        end
+      end
+
+      def on_test_omission(worker, result)
+        synchronize do
+          report_test_result_mark("O", result)
+          puts
+          report_test(worker, result)
+          report_actual(result)
+        end
+      end
+
+      def on_test_no_check(worker, result)
+        synchronize do
+          report_test_result_mark("N", result)
+          puts
+          report_test(worker, result)
+          report_actual(result)
+        end
+      end
+
+      def on_test_finish(worker, result)
+      end
+
+      def on_suite_finish(worker)
+      end
+
+      def on_worker_finish(worker_id)
+      end
+
+      def on_finish(result)
+        puts
+        puts
+        report_summary(result)
+      end
+
+      private
+      def report_test_result_mark(mark, result)
+        if @term_width < @current_column + mark.bytesize
+          puts
+        end
+        print(colorize(mark, result))
+        if @term_width <= @current_column
+          puts
+        else
+          @output.flush
+        end
+      end
+    end
+  end
+end

  Added: lib/grntest/reporters/stream_reporter.rb (+86 -0) 100644
===================================================================
--- /dev/null
+++ lib/grntest/reporters/stream_reporter.rb    2013-08-12 11:39:17 +0900 (7aa5514)
@@ -0,0 +1,86 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2012-2013  Kouhei Sutou <kou �� clear-code.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+require "grntest/reporters/base_reporter"
+
+module Grntest
+  module Reporters
+    class StreamReporter < BaseReporter
+      def initialize(tester)
+        super
+      end
+
+      def on_start(result)
+      end
+
+      def on_worker_start(worker)
+      end
+
+      def on_suite_start(worker)
+        if worker.suite_name.bytesize <= @term_width
+          puts(worker.suite_name)
+        else
+          puts(justify(worker.suite_name, @term_width))
+        end
+        @output.flush
+      end
+
+      def on_test_start(worker)
+        print("  #{worker.test_name}")
+        @output.flush
+      end
+
+      def on_test_success(worker, result)
+        report_test_result(result, worker.status)
+      end
+
+      def on_test_failure(worker, result)
+        report_test_result(result, worker.status)
+        report_failure(result)
+      end
+
+      def on_test_leak(worker, result)
+        report_test_result(result, worker.status)
+        report_actual(result) unless result.checked?
+      end
+
+      def on_test_omission(worker, result)
+        report_test_result(result, worker.status)
+        report_actual(result)
+      end
+
+      def on_test_no_check(worker, result)
+        report_test_result(result, worker.status)
+        report_actual(result)
+      end
+
+      def on_test_finish(worker, result)
+      end
+
+      def on_suite_finish(worker)
+      end
+
+      def on_worker_finish(worker_id)
+      end
+
+      def on_finish(result)
+        puts
+        report_summary(result)
+      end
+    end
+  end
+end

  Modified: lib/grntest/tester.rb (+2 -703)
===================================================================
--- lib/grntest/tester.rb    2013-08-12 11:29:33 +0900 (89e72de)
+++ lib/grntest/tester.rb    2013-08-12 11:39:17 +0900 (c1b480f)
@@ -29,6 +29,7 @@ require "msgpack"
 require "groonga/command"
 
 require "grntest/version"
+require "grntest/reporters"
 
 module Grntest
   class Tester
@@ -662,14 +663,7 @@ module Grntest
       end
 
       def create_reporter
-        case****@teste*****
-        when :mark
-          MarkReporter.new(@tester)
-        when :stream
-          StreamReporter.new(@tester)
-        when :inplace
-          InplaceReporter.new(@tester)
-        end
+        Grntest::Reporters.create_repoter(@tester)
       end
     end
 
@@ -1651,700 +1645,5 @@ EOF
         self.class.new(@host, @port, context)
       end
     end
-
-    class BaseReporter
-      def initialize(tester)
-        @tester = tester
-        @term_width = guess_term_width
-        @output =****@teste*****
-        @mutex = Mutex.new
-        reset_current_column
-      end
-
-      private
-      def synchronize
-        @mutex.synchronize do
-          yield
-        end
-      end
-
-      def report_summary(result)
-        puts(statistics_header)
-        puts(colorize(statistics(result), result))
-        pass_ratio = result.pass_ratio
-        elapsed_time = result.elapsed_time
-        summary = "%.4g%% passed in %.4fs." % [pass_ratio, elapsed_time]
-        puts(colorize(summary, result))
-      end
-
-      def columns
-        [
-          # label,      format value
-          ["tests/sec", lambda {|result| "%9.2f" % throughput(result)}],
-          ["   tests",  lambda {|result| "%8d"   % result.n_tests}],
-          ["  passes",  lambda {|result| "%8d"   % result.n_passed_tests}],
-          ["failures",  lambda {|result| "%8d"   % result.n_failed_tests}],
-          ["  leaked",  lambda {|result| "%8d"   % result.n_leaked_tests}],
-          [" omitted",  lambda {|result| "%8d"   % result.n_omitted_tests}],
-          ["!checked",  lambda {|result| "%8d"   % result.n_not_checked_tests}],
-        ]
-      end
-
-      def statistics_header
-        labels = columns.collect do |label, format_value|
-          label
-        end
-        "  " + labels.join(" | ") + " |"
-      end
-
-      def statistics(result)
-        items = columns.collect do |label, format_value|
-          format_value.call(result)
-        end
-        "  " + items.join(" | ") + " |"
-      end
-
-      def throughput(result)
-        if result.elapsed_time.zero?
-          tests_per_second = 0
-        else
-          tests_per_second = result.n_tests / result.elapsed_time
-        end
-        tests_per_second
-      end
-
-      def report_failure(result)
-        report_marker(result)
-        report_diff(result.expected, result.actual)
-        report_marker(result)
-      end
-
-      def report_actual(result)
-        report_marker(result)
-        puts(result.actual)
-        report_marker(result)
-      end
-
-      def report_marker(result)
-        puts(colorize("=" * @term_width, result))
-      end
-
-      def report_diff(expected, actual)
-        create_temporary_file("expected", expected) do |expected_file|
-          create_temporary_file("actual", actual) do |actual_file|
-            diff_options =****@teste*****_options.dup
-            diff_options.concat(["--label", "(expected)", expected_file.path,
-                                 "--label", "(actual)", actual_file.path])
-            system(@tester.diff, *diff_options)
-          end
-        end
-      end
-
-      def report_test(worker, result)
-        report_marker(result)
-        print("[#{worker.id}] ") if****@teste*****_workers > 1
-        puts(worker.suite_name)
-        print("  #{worker.test_name}")
-        report_test_result(result, worker.status)
-      end
-
-      def report_test_result(result, label)
-        message = test_result_message(result, label)
-        message_width = string_width(message)
-        rest_width = @term_width - @current_column
-        if rest_width > message_width
-          print(" " * (rest_width - message_width))
-        end
-        puts(message)
-      end
-
-      def test_result_message(result, label)
-        elapsed_time = result.elapsed_time
-        formatted_elapsed_time = "%.4fs" % elapsed_time
-        formatted_elapsed_time = colorize(formatted_elapsed_time,
-                                          elapsed_time_status(elapsed_time))
-        " #{formatted_elapsed_time} [#{colorize(label, result)}]"
-      end
-
-      LONG_ELAPSED_TIME = 1.0
-      def long_elapsed_time?(elapsed_time)
-        elapsed_time >= LONG_ELAPSED_TIME
-      end
-
-      def elapsed_time_status(elapsed_time)
-        if long_elapsed_time?(elapsed_time)
-          elapsed_time_status = :failure
-        else
-          elapsed_time_status = :not_checked
-        end
-      end
-
-      def justify(message, width)
-        return " " * width if message.nil?
-        return message.ljust(width) if message.bytesize <= width
-        half_width = width / 2.0
-        elision_mark = "..."
-        left = message[0, half_width.ceil - elision_mark.size]
-        right = message[(message.size - half_width.floor)..-1]
-        "#{left}#{elision_mark}#{right}"
-      end
-
-      def print(message)
-        @current_column += string_width(message.to_s)
-        @output.print(message)
-      end
-
-      def puts(*messages)
-        reset_current_column
-        @output.puts(*messages)
-      end
-
-      def reset_current_column
-        @current_column = 0
-      end
-
-      def create_temporary_file(key, content)
-        file = Tempfile.new("groonga-test-#{key}")
-        file.print(content)
-        file.close
-        yield(file)
-      end
-
-      def guess_term_width
-        Integer(guess_term_width_from_env || guess_term_width_from_stty || 79)
-      rescue ArgumentError
-        0
-      end
-
-      def guess_term_width_from_env
-        ENV["COLUMNS"] || ENV["TERM_WIDTH"]
-      end
-
-      def guess_term_width_from_stty
-        return nil unless STDIN.tty?
-
-        case tty_info
-        when /(\d+) columns/
-          $1
-        when /columns (\d+)/
-          $1
-        else
-          nil
-        end
-      end
-
-      def tty_info
-        begin
-          `stty -a`
-        rescue SystemCallError
-          nil
-        end
-      end
-
-      def string_width(string)
-        string.gsub(/\e\[[0-9;]+m/, "").size
-      end
-
-      def result_status(result)
-        if result.respond_to?(:status)
-          result.status
-        else
-          if result.n_failed_tests > 0
-            :failure
-          elsif result.n_leaked_tests > 0
-            :leaked
-          elsif result.n_omitted_tests > 0
-            :omitted
-          elsif result.n_not_checked_tests > 0
-            :not_checked
-          else
-            :success
-          end
-        end
-      end
-
-      def colorize(message, result_or_status)
-        return message unles****@teste*****_color?
-        if result_or_status.is_a?(Symbol)
-          status = result_or_status
-        else
-          status = result_status(result_or_status)
-        end
-        case status
-        when :success
-          "%s%s%s" % [success_color, message, reset_color]
-        when :failure
-          "%s%s%s" % [failure_color, message, reset_color]
-        when :leaked
-          "%s%s%s" % [leaked_color, message, reset_color]
-        when :omitted
-          "%s%s%s" % [omitted_color, message, reset_color]
-        when :not_checked
-          "%s%s%s" % [not_checked_color, message, reset_color]
-        else
-          message
-        end
-      end
-
-      def success_color
-        escape_sequence({
-                          :color => :green,
-                          :color_256 => [0, 3, 0],
-                          :background => true,
-                        },
-                        {
-                          :color => :white,
-                          :color_256 => [5, 5, 5],
-                          :bold => true,
-                        })
-      end
-
-      def failure_color
-        escape_sequence({
-                          :color => :red,
-                          :color_256 => [3, 0, 0],
-                          :background => true,
-                        },
-                        {
-                          :color => :white,
-                          :color_256 => [5, 5, 5],
-                          :bold => true,
-                        })
-      end
-
-      def leaked_color
-        escape_sequence({
-                          :color => :magenta,
-                          :color_256 => [3, 0, 3],
-                          :background => true,
-                        },
-                        {
-                          :color => :white,
-                          :color_256 => [5, 5, 5],
-                          :bold => true,
-                        })
-      end
-
-      def omitted_color
-        escape_sequence({
-                          :color => :blue,
-                          :color_256 => [0, 0, 1],
-                          :background => true,
-                        },
-                        {
-                          :color => :white,
-                          :color_256 => [5, 5, 5],
-                          :bold => true,
-                        })
-      end
-
-      def not_checked_color
-        escape_sequence({
-                          :color => :cyan,
-                          :color_256 => [0, 1, 1],
-                          :background => true,
-                        },
-                        {
-                          :color => :white,
-                          :color_256 => [5, 5, 5],
-                          :bold => true,
-                        })
-      end
-
-      def reset_color
-        escape_sequence(:reset)
-      end
-
-      COLOR_NAMES = [
-        :black, :red, :green, :yellow,
-        :blue, :magenta, :cyan, :white,
-      ]
-      def escape_sequence(*commands)
-        sequence = []
-        commands.each do |command|
-          case command
-          when :reset
-            sequence << "0"
-          when :bold
-            sequence << "1"
-          when :italic
-            sequence << "3"
-          when :underline
-            sequence << "4"
-          when Hash
-            foreground_p = !command[:background]
-            if available_colors == 256
-              sequence << (foreground_p ? "38" : "48")
-              sequence << "5"
-              sequence << pack_256_color(*command[:color_256])
-            else
-              color_parameter = foreground_p ? 3 : 4
-              color_parameter += 6 if command[:intensity]
-              color = COLOR_NAMES.index(command[:color])
-              sequence << "#{color_parameter}#{color}"
-            end
-          end
-        end
-        "\e[#{sequence.join(';')}m"
-      end
-
-      def pack_256_color(red, green, blue)
-        red * 36 + green * 6 + blue + 16
-      end
-
-      def available_colors
-        case ENV["COLORTERM"]
-        when "gnome-terminal"
-          256
-        else
-          case ENV["TERM"]
-          when /-256color\z/
-            256
-          else
-            8
-          end
-        end
-      end
-    end
-
-    class MarkReporter < BaseReporter
-      def initialize(tester)
-        super
-      end
-
-      def on_start(result)
-      end
-
-      def on_worker_start(worker)
-      end
-
-      def on_suite_start(worker)
-      end
-
-      def on_test_start(worker)
-      end
-
-      def on_test_success(worker, result)
-        synchronize do
-          report_test_result_mark(".", result)
-        end
-      end
-
-      def on_test_failure(worker, result)
-        synchronize do
-          report_test_result_mark("F", result)
-          puts
-          report_test(worker, result)
-          report_failure(result)
-        end
-      end
-
-      def on_test_leak(worker, result)
-        synchronize do
-          report_test_result_mark("L(#{result.n_leaked_objects})", result)
-          unless result.checked?
-            puts
-            report_test(worker, result)
-            report_actual(result)
-          end
-        end
-      end
-
-      def on_test_omission(worker, result)
-        synchronize do
-          report_test_result_mark("O", result)
-          puts
-          report_test(worker, result)
-          report_actual(result)
-        end
-      end
-
-      def on_test_no_check(worker, result)
-        synchronize do
-          report_test_result_mark("N", result)
-          puts
-          report_test(worker, result)
-          report_actual(result)
-        end
-      end
-
-      def on_test_finish(worker, result)
-      end
-
-      def on_suite_finish(worker)
-      end
-
-      def on_worker_finish(worker_id)
-      end
-
-      def on_finish(result)
-        puts
-        puts
-        report_summary(result)
-      end
-
-      private
-      def report_test_result_mark(mark, result)
-        if @term_width < @current_column + mark.bytesize
-          puts
-        end
-        print(colorize(mark, result))
-        if @term_width <= @current_column
-          puts
-        else
-          @output.flush
-        end
-      end
-    end
-
-    class StreamReporter < BaseReporter
-      def initialize(tester)
-        super
-      end
-
-      def on_start(result)
-      end
-
-      def on_worker_start(worker)
-      end
-
-      def on_suite_start(worker)
-        if worker.suite_name.bytesize <= @term_width
-          puts(worker.suite_name)
-        else
-          puts(justify(worker.suite_name, @term_width))
-        end
-        @output.flush
-      end
-
-      def on_test_start(worker)
-        print("  #{worker.test_name}")
-        @output.flush
-      end
-
-      def on_test_success(worker, result)
-        report_test_result(result, worker.status)
-      end
-
-      def on_test_failure(worker, result)
-        report_test_result(result, worker.status)
-        report_failure(result)
-      end
-
-      def on_test_leak(worker, result)
-        report_test_result(result, worker.status)
-        report_actual(result) unless result.checked?
-      end
-
-      def on_test_omission(worker, result)
-        report_test_result(result, worker.status)
-        report_actual(result)
-      end
-
-      def on_test_no_check(worker, result)
-        report_test_result(result, worker.status)
-        report_actual(result)
-      end
-
-      def on_test_finish(worker, result)
-      end
-
-      def on_suite_finish(worker)
-      end
-
-      def on_worker_finish(worker_id)
-      end
-
-      def on_finish(result)
-        puts
-        report_summary(result)
-      end
-    end
-
-    class InplaceReporter < BaseReporter
-      def initialize(tester)
-        super
-        @last_redraw_time = Time.now
-        @minimum_redraw_interval = 0.1
-      end
-
-      def on_start(result)
-        @test_suites_result = result
-      end
-
-      def on_worker_start(worker)
-      end
-
-      def on_suite_start(worker)
-        redraw
-      end
-
-      def on_test_start(worker)
-        redraw
-      end
-
-      def on_test_success(worker, result)
-        redraw
-      end
-
-      def on_test_failure(worker, result)
-        redraw do
-          report_test(worker, result)
-          report_failure(result)
-        end
-      end
-
-      def on_test_leak(worker, result)
-        redraw do
-          report_test(worker, result)
-          report_marker(result)
-          report_actual(result) unless result.checked?
-        end
-      end
-
-      def on_test_omission(worker, result)
-        redraw do
-          report_test(worker, result)
-          report_actual(result)
-        end
-      end
-
-      def on_test_no_check(worker, result)
-        redraw do
-          report_test(worker, result)
-          report_actual(result)
-        end
-      end
-
-      def on_test_finish(worker, result)
-        redraw
-      end
-
-      def on_suite_finish(worker)
-        redraw
-      end
-
-      def on_worker_finish(worker)
-        redraw
-      end
-
-      def on_finish(result)
-        draw
-        puts
-        report_summary(result)
-      end
-
-      private
-      def draw
-        draw_statistics_header_line
-        @test_suites_result.workers.each do |worker|
-          draw_status_line(worker)
-          draw_test_line(worker)
-        end
-        draw_progress_line
-      end
-
-      def draw_statistics_header_line
-        puts(statistics_header)
-      end
-
-      def draw_status_line(worker)
-        clear_line
-        left = "[#{colorize(worker.id, worker.result)}] "
-        right = " [#{worker.status}]"
-        rest_width = @term_width - @current_column
-        center_width = rest_width - string_width(left) - string_width(right)
-        center = justify(worker.suite_name, center_width)
-        puts("#{left}#{center}#{right}")
-      end
-
-      def draw_test_line(worker)
-        clear_line
-        if worker.test_name
-          label = "  #{worker.test_name}"
-        else
-          label = statistics(worker.result)
-        end
-        puts(justify(label, @term_width))
-      end
-
-      def draw_progress_line
-        n_done_tests = @test_suites_result.n_tests
-        n_total_tests = @test_suites_result.n_total_tests
-        if n_total_tests.zero?
-          finished_test_ratio = 0.0
-        else
-          finished_test_ratio = n_done_tests.to_f / n_total_tests
-        end
-
-        start_mark = "|"
-        finish_mark = "|"
-        statistics = " [%3d%%]" % (finished_test_ratio * 100)
-
-        progress_width = @term_width
-        progress_width -= start_mark.bytesize
-        progress_width -= finish_mark.bytesize
-        progress_width -= statistics.bytesize
-        finished_mark = "-"
-        if n_done_tests == n_total_tests
-          progress = colorize(finished_mark * progress_width,
-                              @test_suites_result)
-        else
-          current_mark = ">"
-          finished_marks_width = (progress_width * finished_test_ratio).ceil
-          finished_marks_width -= current_mark.bytesize
-          finished_marks_width = [0, finished_marks_width].max
-          progress = finished_mark * finished_marks_width + current_mark
-          progress = colorize(progress, @test_suites_result)
-          progress << " " * (progress_width - string_width(progress))
-        end
-        puts("#{start_mark}#{progress}#{finish_mark}#{statistics}")
-      end
-
-      def redraw
-        synchronize do
-          unless block_given?
-            return if Time.now - @last_redraw_time < @minimum_redraw_interval
-          end
-          draw
-          if block_given?
-            yield
-          else
-            up_n_lines(n_using_lines)
-          end
-          @last_redraw_time = Time.now
-        end
-      end
-
-      def up_n_lines(n)
-        print("\e[1A" * n)
-      end
-
-      def clear_line
-        print(" " * @term_width)
-        print("\r")
-        reset_current_column
-      end
-
-      def n_using_lines
-        n_statistics_header_line + n_worker_lines * n_workers + n_progress_lines
-      end
-
-      def n_statistics_header_line
-        1
-      end
-
-      def n_worker_lines
-        2
-      end
-
-      def n_progress_lines
-        1
-      end
-
-      def n_workers
-        @tester.n_workers
-      end
-    end
   end
 end
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index