#!/usr/bin/env ruby # encoding: UTF-8 require 'tins/xt' require 'tins/lines_file' include Tins::GO require 'utils' include Utils require 'drb' def usage puts <<-EOT Usage: #{File.basename($0)} [OPTS] FILENAME[:LINENO] [FILENAME] Options are -n TESTNAME run the test TESTNAME in file FILENAME -t FRAMEWORK use test framework FRAMEWORK (rspec, test-unit or cucumber) -c start probe as a client -C start probe as a client console -l start probe as a server -p PORT listen on/connect to local port PORT -h display this help Version is #{File.basename($0)} #{Utils::VERSION}. EOT exit 1 end def cmd(*args) puts args * ' ' system(*args) or exit $?.exitstatus end def find_cmd(*cmds) cmds.map { |c| `which #{c}`.full?(:chomp) }.compact.first or raise fail "no #{cmds * '|'} command found" end $config = Utils::Config::ConfigFile.new $config.configure_from_paths testrunner_args = [] if i = ARGV.index('--') testrunner_args.concat ARGV[(i + 1)..-1] $args = ARGV[0...i] else $args = ARGV.dup end $opt = go 'lcCp:t:n:h', $args $opt['h'] and usage $uri = "druby://localhost:#{$opt['p'] || 6623}" def start_server Thread.abort_on_exception = $DEBUG begin DRb.start_service DRbObject.new_with_uri($uri).shutdown rescue DRb::DRbConnError end puts "Starting probe server listening to #{$uri.inspect}." DRb.start_service($uri, Utils::ProbeServer.new) begin DRb.thread.join rescue Interrupt warn " *** Interrupted ***" exit end end def connect_server puts "Connecting probe server on #{$uri.inspect}." DRb.start_service probe_server = DRbObject.new_with_uri($uri) if $opt['c'] opts = $opt.subhash('n', 't').map { |k, v| v.full? { "-#{k} #{v.inspect}" } }.compact probe_server.enqueue opts + $args exit elsif $opt['C'] ARGV.clear Tins::IRB.examine probe_server exit end end case when $opt['l'] start_server else connect_server end $args.empty? and fail "require filename or filename:linenumber as arguments" puts "Running tests in #{$args.inspect}" case ($opt['t'] || $config.probe.test_framework).to_sym when :rspec rspec = find_cmd('rspec', 'spec') if linenumber = $opt['n'] cmd 'ruby', '-I', $config.probe.include_dirs_argument, rspec, '-l', linenumber, *($args + testrunner_args) else $args = $args.map do |a| if Utils::Editor::FILE_LINENUMBER_REGEXP =~ a $~.captures * ':' else a end end cmd 'ruby', '-I', $config.probe.include_dirs_argument, rspec, *($args + testrunner_args) end when :'test-unit' testrb = find_cmd('testrb') if testname = $opt['n'] cmd 'ruby', '-I', $config.probe.include_dirs_argument, testrb, '-n', testname, *($args + testrunner_args) else for filename in $args sl = filename.source_location if sl.linenumber lf = Tins::LinesFile.for_filename(*sl) if testname = lf.match_backward(/def\s+(\S+?)(?:\(|\s*$)/).full?(:first) cmd 'ruby', '-I', $config.probe.include_dirs_argument, testrb, '-n', testname, sl.filename, *testrunner_args else warn "no test found before line #{sl.linenumber}" end else cmd 'ruby', '-I', $config.probe.include_dirs_argument, testrb, sl.filename, *testrunner_args end end end when :cucumber cucumber = find_cmd('cucumber') if linenumber = $opt['n'] cmd 'ruby', cucumber, '-r', $config.probe.include_dirs_argument, '-l', linenumber, *($args + testrunner_args) else $args = $args.map do |a| if Utils::Editor::FILE_LINENUMBER_REGEXP =~ a $~.captures * ':' else a end end cmd 'ruby', cucumber, '-r', $config.probe.include_dirs_argument, *($args + testrunner_args) end end