[Groonga-commit] groonga/groonga-test [master] Move to lib/groonga/tester.rb

アーカイブの一覧に戻る

null+****@clear***** null+****@clear*****
2012年 3月 6日 (火) 16:10:00 JST


Kouhei Sutou	2012-03-06 16:10:00 +0900 (Tue, 06 Mar 2012)

  New Revision: e087ca7e87174d441b4d54b659a2232d0982cfee

  Log:
    Move to lib/groonga/tester.rb

  Copied files:
    lib/groonga/tester.rb
      (from bin/groonga-test)
  Modified files:
    bin/groonga-test

  Modified: bin/groonga-test (+1 -565)
===================================================================
--- bin/groonga-test    2012-03-06 16:06:25 +0900 (044c447)
+++ bin/groonga-test    2012-03-06 16:10:00 +0900 (afc2bf6)
@@ -15,570 +15,6 @@
 # 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 "English"
-require "optparse"
-require "pathname"
-require "fileutils"
-require "tempfile"
-require "json"
-require "shellwords"
-
-class GroongaTester
-  VERSION = "1.0.0"
-
-  class << self
-    def run(argv=nil)
-      argv ||= ARGV.dup
-      tester = new
-      catch do |tag|
-        parser = create_option_parser(tester, tag)
-        targets = parser.parse!(argv)
-        tester.run(*targets)
-      end
-    end
-
-    private
-    def create_option_parser(tester, tag)
-      parser = OptionParser.new
-      parser.banner += " TEST_FILE_OR_DIRECTORY..."
-
-      parser.on("--groonga=COMMAND",
-                "Use COMMAND as groonga command",
-                "(#{tester.groonga})") do |command|
-        tester.groonga = command
-      end
-
-      parser.on("--groonga-suggest-create-dataset=COMMAND",
-                "Use COMMAND as groonga_suggest_create_dataset command",
-                "(#{tester.groonga_suggest_create_dataset})") do |command|
-        tester.groonga_suggest_create_dataset = command
-      end
-
-      parser.on("--base-directory=DIRECTORY",
-                "Use DIRECTORY as a base directory of relative path",
-                "(#{tester.base_directory})") do |directory|
-        tester.base_directory = directory
-      end
-
-      parser.on("--diff=DIFF",
-                "Use DIFF as diff command",
-                "(#{tester.diff})") do |diff|
-        tester.diff = diff
-        tester.diff_options.clear
-      end
-
-      diff_option_is_specified = false
-      parser.on("--diff-option=OPTION",
-                "Use OPTION as diff command",
-                "(#{tester.diff_options.join(' ')})") do |option|
-        tester.diff_options.clear if diff_option_is_specified
-        tester.diff_options << option
-        diff_option_is_specified = true
-      end
-
-      parser.on("--version",
-                "Show version and exit") do
-        puts(GroongaTester::VERSION)
-        throw(tag, true)
-      end
-
-      parser
-    end
-  end
-
-  attr_accessor :groonga, :groonga_suggest_create_dataset
-  attr_accessor :base_directory, :diff, :diff_options
-  def initialize
-    @groonga = "groonga"
-    @groonga_suggest_create_dataset = "groonga-suggest-create-dataset"
-    @base_directory = "."
-    detect_suitable_diff
-  end
-
-  def run(*targets)
-    succeeded = true
-    return succeeded if targets.empty?
-
-    reporter = Reporter.new(self)
-    reporter.start
-    targets.each do |target|
-      target_path = Pathname(target)
-      next unless target_path.exist?
-      if target_path.directory?
-        Dir.glob(target_path + "**" + "*.test") do |target_file|
-          succeeded = false unless run_test(Pathname(target_file), reporter)
-        end
-      else
-        succeeded = false unless run_test(target_path, reporter)
-      end
-    end
-    reporter.finish
-    succeeded
-  end
-
-  private
-  def run_test(test_script_path, reporter)
-    runner = Runner.new(self, test_script_path)
-    runner.run(reporter)
-  end
-
-  def detect_suitable_diff
-    if command_exist?("cut-diff")
-      @diff = "cut-diff"
-      @diff_options = ["--context-lines", "10"]
-    else
-      @diff = "diff"
-      @diff_options = ["-u"]
-    end
-  end
-
-  def command_exist?(name)
-    ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
-      absolute_path = File.join(path, name)
-      return true if File.executable?(absolute_path)
-    end
-    false
-  end
-
-  class Runner
-    MAX_N_COLUMNS = 79
-
-    def initialize(tester, test_script_path)
-      @tester = tester
-      @test_script_path = test_script_path
-      @max_n_columns = MAX_N_COLUMNS
-    end
-
-    def run(reporter)
-      succeeded = true
-
-      reporter.start_test(@test_script_path)
-      actual_result = run_groonga_script
-      actual_result = normalize_result(actual_result)
-      expected_result = read_expected_result
-      if expected_result
-        if actual_result == expected_result
-          reporter.pass_test
-          remove_reject_file
-        else
-          reporter.fail_test(expected_result, actual_result)
-          output_reject_file(actual_result)
-          succeeded = false
-        end
-      else
-        reporter.no_check_test(actual_result)
-        output_actual_file(actual_result)
-      end
-      reporter.finish_test
-
-      succeeded
-    end
-
-    private
-    def run_groonga_script
-      create_temporary_directory do |directory_path|
-        run_groonga(File.join(directory_path, "db")) do |io|
-          context = Executer::Context.new
-          context.base_directory =****@teste*****_directory
-          executer = Executer.new(io, context)
-          executer.execute(@test_script_path)
-        end
-      end
-    end
-
-    def create_temporary_directory
-      path = "tmp"
-      FileUtils.rm_rf(path)
-      FileUtils.mkdir_p(path)
-      begin
-        yield path
-      ensure
-        FileUtils.rm_rf(path)
-      end
-    end
-
-    def run_groonga(db_path)
-      IO.popen([@tester.groonga, "-n", db_path], "r+") do |io|
-        begin
-          yield io
-        ensure
-          io.close unless io.closed?
-        end
-      end
-    end
-
-    def normalize_result(result)
-      normalized_result = ""
-      result.each do |tag, content, options|
-        case tag
-        when :input
-          normalized_result << content
-        when :output
-          case options[:format]
-          when "json"
-            status, *values = JSON.parse(content)
-            normalized_status = normalize_status(status)
-            normalized_output_content = [normalized_status, *values]
-            normalized_output = JSON.generate(normalized_output_content)
-            if normalized_output.bytesize > @max_n_columns
-              normalized_output = JSON.pretty_generate(normalized_output_content)
-            end
-            normalized_output.force_encoding("ASCII-8BIT")
-            normalized_result << "#{normalized_output}\n"
-          else
-            normalized_result << "#{content}\n".force_encoding("ASCII-8BIT")
-          end
-        when :error
-          normalized_result << "#{content}\n".force_encoding("ASCII-8BIT")
-        end
-      end
-      normalized_result
-    end
-
-    def normalize_status(status)
-      return_code, started_time, elapsed_time, *rest = status
-      if return_code.zero?
-        [0, 0.0, 0.0]
-      else
-        message, bactrace = rest
-        [[return_code, 0.0, 0.0], message]
-      end
-    end
-
-    def have_extension?
-      not @test_script_path.extname.empty?
-    end
-
-    def related_file_path(extension)
-      path = Pathname(@test_script_path.to_s.gsub(/\.[^.]+\z/, ".#{extension}"))
-      return nil if @test_script_path == path
-      path
-    end
-
-    def read_expected_result
-      return nil unless have_extension?
-      result_path = related_file_path("expected")
-      return nil if result_path.nil?
-      return nil unless result_path.exist?
-      result_path.open("r:ascii-8bit") do |result_file|
-        result_file.read
-      end
-    end
-
-    def remove_reject_file
-      return unless have_extension?
-      reject_path = related_file_path("reject")
-      return if reject_path.nil?
-      FileUtils.rm_rf(reject_path.to_s)
-    end
-
-    def output_reject_file(actual_result)
-      output_actual_result(actual_result, "reject")
-    end
-
-    def output_actual_file(actual_result)
-      output_actual_result(actual_result, "actual")
-    end
-
-    def output_actual_result(actual_result, suffix)
-      result_path = related_file_path(suffix)
-      return if result_path.nil?
-      result_path.open("w:ascii-8bit") do |result_file|
-        result_file.print(actual_result)
-      end
-    end
-  end
-
-  class Executer
-    class Context
-      attr_accessor :logging, :base_directory, :result
-      def initialize
-        @logging = true
-        @base_directory = "."
-        @n_nested = 0
-        @result = []
-      end
-
-      def execute
-        @n_nested += 1
-        yield
-      ensure
-        @n_nested -= 1
-      end
-
-      def top_level?
-        @n_nested == 1
-      end
-    end
-
-    class Error < StandardError
-    end
-
-    class NotExist < Error
-      attr_reader :path
-      def initialize(path)
-        @path = path
-        super("<#{path}> doesn't exist.")
-      end
-    end
-
-    def initialize(groonga, context=nil)
-      @groonga = groonga
-      @loading = false
-      @pending_command = ""
-      @current_command_name = nil
-      @output_format = nil
-      @context = context || Context.new
-    end
-
-    def execute(script_path)
-      unless script_path.exist?
-        raise NotExist.new(script_path)
-      end
-
-      @context.execute do
-        script_path.open("r:ascii-8bit") do |script_file|
-          script_file.each_line do |line|
-            begin
-              if @loading
-                execute_line_on_loading(line)
-              else
-                execute_line_with_continuation_line_support(line)
-              end
-            rescue Error
-              line_info = "#{script_path}:#{script_file.lineno}:#{line.chomp}"
-              log_error("#{line_info}: #{$!.message}")
-              raise unles****@conte*****_level?
-            end
-          end
-        end
-      end
-
-      @context.result
-    end
-
-    private
-    def execute_line_on_loading(line)
-      log_input(line)
-      @groonga.print(line)
-      @groonga.flush
-      if /\]$/ =~ line
-        current_result = read_output
-        unless current_result.empty?
-          @loading = false
-          log_output(current_result)
-        end
-      end
-    end
-
-    def execute_line_with_continuation_line_support(line)
-      if /\\$/ =~ line
-        @pending_command << $PREMATCH
-      else
-        if @pending_command.empty?
-          execute_line(line)
-        else
-          @pending_command << line
-          execute_line(@pending_command)
-          @pending_command = ""
-        end
-      end
-    end
-
-    def execute_line(line)
-      case line
-      when /\A\s*\z/
-        # do nothing
-      when /\A\s*\#/
-        comment_content = $POSTMATCH
-        execute_comment(comment_content)
-      else
-        execute_command(line)
-      end
-    end
-
-    def execute_comment(content)
-      case content.strip
-      when "disable-logging"
-        @context.logging = false
-      when "enable-logging"
-        @context.logging = true
-      when /\Ainclude\s+/
-        path = $POSTMATCH.strip
-        return if path.empty?
-        execute_script(path)
-      end
-    end
-
-    def execute_script(path)
-      executer = self.class.new(@groonga, @context)
-      script_path = Pathname(path)
-      if script_path.relative?
-        script_path = Pathname(@context.base_directory) + script_path
-      end
-      executer.execute(script_path)
-    end
-
-    def execute_command(line)
-      extract_command_info(line)
-      @loading = true if @current_command == "load"
-      log_input(line)
-      @groonga.print(line)
-      @groonga.flush
-      unless @loading
-        log_output(read_output)
-      end
-    end
-
-    def extract_command_info(line)
-      words = Shellwords.split(line)
-      @current_command = words.shift
-      if @current_command == "dump"
-        @output_format = "groonga-command"
-      else
-        @output_format = "json"
-        words.each_with_index do |word, i|
-          if /\A--output_format(?:=(.+))?\z/ =~ word
-            @output_format = $1 || words[i + 1]
-            break
-          end
-        end
-      end
-    end
-
-    def read_output
-      output = ""
-      first_timeout = 1
-      timeout = first_timeout
-      while IO.select([@groonga], [], [], timeout)
-        break if****@groon*****?
-        output << @groonga.readpartial(65535)
-        timeout = 0
-      end
-      output
-    end
-
-    def log(tag, content, options={})
-      return unles****@conte*****
-      return if content.empty?
-      log_force(tag, content, options)
-    end
-
-    def log_force(tag, content, options)
-      @context.result << [tag, content, options]
-    end
-
-    def log_input(content)
-      log(:input, content)
-    end
-
-    def log_output(content)
-      log(:output, content,
-          :command => @current_command,
-          :format => @output_format)
-    end
-
-    def log_error(content)
-      log_force(:error, content)
-    end
-  end
-
-  class Reporter
-    def initialize(tester)
-      @tester = tester
-      @term_width = guess_term_width
-      @current_column = 0
-      @output = STDOUT
-      @n_tests = 0
-      @n_passed_tests = 0
-      @failed_tests = []
-    end
-
-    def start
-    end
-
-    def start_test(test_script_path)
-      @test_name = test_script_path.basename
-      print("  #{@test_name}")
-      @output.flush
-    end
-
-    def pass_test
-      report_test_result("pass")
-      @n_passed_tests += 1
-    end
-
-    def fail_test(expected, actual)
-      report_test_result("fail")
-      puts("=" * @term_width)
-      report_diff(expected, actual)
-      puts("=" * @term_width)
-      @failed_tests << @test_name
-    end
-
-    def no_check_test(result)
-      report_test_result("not checked")
-      puts(result)
-    end
-
-    def finish_test
-      @n_tests += 1
-    end
-
-    def finish
-      puts
-      puts("#{@n_tests} tests, " +
-           "#{@n_passed_tests} passes, " +
-           "#{@failed_tests.size} failures.")
-      if @n_tests.zero?
-        pass_ratio = 0
-      else
-        pass_ratio = (@n_passed_tests / @n_tests.to_f) * 100
-      end
-      puts("%.4g%% passed." % pass_ratio)
-    end
-
-    private
-    def print(message)
-      @current_column += message.to_s.size
-      @output.print(message)
-    end
-
-    def puts(*messages)
-      @current_column = 0
-      @output.puts(*messages)
-    end
-
-    def report_test_result(label)
-      message = " [#{label}]"
-      message = message.rjust(@term_width - @current_column) if @term_width > 0
-      puts(message)
-    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", "(actual)", actual_file.path,
-                               "--label", "(expected)", expected_file.path])
-          system(@tester.diff, *diff_options)
-        end
-      end
-    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(ENV["COLUMNS"] || ENV["TERM_WIDTH"] || 79)
-    rescue ArgumentError
-      0
-    end
-  end
-end
+require "groonga/tester"
 
 exit(GroongaTester.run)

  Copied: lib/groonga/tester.rb (+0 -2) 99%
===================================================================
--- bin/groonga-test    2012-03-06 16:06:25 +0900 (044c447)
+++ lib/groonga/tester.rb    2012-03-06 16:10:00 +0900 (e4b8504)
@@ -580,5 +580,3 @@ class GroongaTester
     end
   end
 end
-
-exit(GroongaTester.run)




Groonga-commit メーリングリストの案内
アーカイブの一覧に戻る