require 'timeout' module RSpactor class Interactor attr_reader :runner def initialize(runner) @runner = runner ticker end def self.ticker_msg(msg, seconds_to_wait = 3, &block) $stdout.print msg if block @yielding_ticker = true Thread.new do loop do $stdout.print('.') if @yielding_ticker == true $stdout.flush sleep 1.0 end end yield @yielding_ticker = false else seconds_to_wait.times do $stdout.print('.') $stdout.flush sleep 1 end end $stdout.puts "\n" end def wait_for_enter_key(msg, seconds_to_wait, clear = runner.options[:clear]) begin Timeout::timeout(seconds_to_wait) do system("clear;") if clear ticker(:start => true, :msg => msg) $stdin.gets return true end rescue Timeout::Error false ensure ticker(:stop => true) end end def start_termination_handler @main_thread = Thread.current Thread.new do loop do sleep 0.5 if entry = $stdin.gets case entry when "c\n" # Cucumber: current tagged feature runner.run_cucumber_command when "ca\n" # Cucumber All: ~pending tagged feature runner.run_cucumber_command('~@wip,~@pending') when "r\n" runner.spork.reload if runner.spork else if wait_for_enter_key("** Running all specs... Hit again to exit RSpactor", 1) @main_thread.exit exit end runner.run_all_specs end end end end end private def ticker(opts = {}) if opts[:stop] $stdout.puts "\n" @pointer_running = false elsif opts[:start] @pointer_running = true write(opts[:msg]) if opts[:msg] else Thread.new do loop do write('.') if @pointer_running == true sleep 1.0 end end end end def write(msg) $stdout.print(msg) $stdout.flush end end end