#!/usr/bin/env ruby

require 'getoptlong'
require 'runit/testcase'
require 'runit/cui/testrunner'

# --------------------------------------------------------------------
# The default format for test output messes up the error line
# detection of emacs.  Hence we have provided an Emacs friendly
# version of the test runner.

class EmacsTestRunner < RUNIT::CUI::TestRunner
  def start_test(t)
    @io.print "\n", t.name, " " if @@quiet_mode
  end
  def end_test(t)
    @io.print "." if $show_dots
  end
end

# Helper Functions ---------------------------------------------------

class RunRubyTests
  def parse_options
    option_definitions = [
      ['--verbose', '-v', GetoptLong::NO_ARGUMENT],
      ['--usage',   '-h', '-u', GetoptLong::NO_ARGUMENT],
      ['--help',    '-H', GetoptLong::NO_ARGUMENT],
      ['--dots',    '-d', GetoptLong::NO_ARGUMENT],
      ['--testdir', '-t', GetoptLong::REQUIRED_ARGUMENT],
      ['--run',     '-r', GetoptLong::REQUIRED_ARGUMENT]
    ]
    parser = GetoptLong.new (*option_definitions)
    
    $testdir = '.'
    $verbose = false
    $runtest = nil
    parser.each do |key, value|
      case key
      when '--verbose'
	$verbose = true
      when '--dots'
	$show_dots = true
      when '--testdir'
	$testdir = value
      when '--run'
	$runtest = value
      when '--usage'
	puts "Usage: runrunit [-dhHuv] [-t dir] [testcases...]"
	exit
      when '--help'
	puts "Go help yourself"
	exit
      end
    end
  end
  
  def find_tests
    testnames = ARGV
    if testnames.length == 0 then
      testnames = Dir.new($testdir).grep (/^test.*\.rb$/)
    end
    testnames
  end
  
  def load_tests (testnames)
    master_test_list = RUNIT::TestSuite.new
    testnames.each do |testname|
      load "#{$testdir}/#{testname}"
      master_test_list.add_test ($last_suite)
    end
    master_test_list
  end
  
  def run_tests(testlist)
    EmacsTestRunner.quiet_mode = !$verbose
    EmacsTestRunner.new.run (testlist)
  end

  def main
    parse_options
    testnames = find_tests
    if $runtest then
      testlist = load_tests ([$runtest])
    else
      testlist = load_tests (testnames)
    end
    run_tests (testlist)
  end
end
  
# Main ---------------------------------------------------------------

if __FILE__ == $0 then
  $:.unshift('.')
  RunRubyTests.new.main
end
