require 'rubygems' require 'eventmachine' $cache_file = File.join(File.dirname(__FILE__), '..', 'tmp', 'stubbing.cache') $log_file = File.join(File.dirname(__FILE__), '..', 'tmp', 'echoserver.log') $sleep_time = 1.5 # may need to increase this depending on ur machine's prowess $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) require 'cross-stub' class AnyClass def self.say_world 'u say world' end class Inner def self.say_world 'u say world' end end end module AnyModule def self.say_world 'u say world' end module Inner def self.say_world 'u say world' end end end module EchoClient class << self attr_accessor :result def get(klass_and_method) address, port = EchoServer::ADDRESS, EchoServer::PORT EventMachine::run do (EventMachine::connect(address, port, EM)). execute(klass_and_method) {|data| self.result = Marshal.load(data) } end self.result end end private module EM def receive_data(data) @callback[data] EventMachine::stop_event_loop end def execute(method, &blk) @callback = blk send_data method end end end module EchoServer ADDRESS, PORT = '127.0.0.1', 8081 class << self def pid @process.pid end def start(other_process=false) unless other_process @process = IO.popen("ruby #{__FILE__}") sleep $sleep_time else EventMachine::run { EventMachine::start_server(ADDRESS, PORT, EM) } end end def stop Process.kill('SIGHUP', pid) end end private module EM def receive_data(klass_and_method) log "(1) EchoServer::EM#receive_data ... receives: #{klass_and_method}" CrossStub.refresh(:file => $cache_file) log "(2) EchoServer::EM#receive_data ... completes stubs refresh" klass, method, *args = klass_and_method.split('.') konst = klass.split(/::/).inject(Object) { |const_train, const| const_train.const_get(const) } log "(3) EchoServer::EM#receive_data ... parses arguments to:", " * klass ... #{klass}", " * method ... #{method}", " * args ... #{args.inspect}" value = args.empty? ? konst.send(method) : konst.send(method, *args) rescue $!.message log "(4) EchoServer::EM#receive_data ... returns: #{value.inspect}" send_data(Marshal.dump(value)) log "(5) EchoServer::EM#receive_data ... end" end def log(*msg) $logger << [msg, ""].flatten.join("\n") end end end if $0 == __FILE__ begin require 'logger' $logger = Logger.new($log_file) EchoServer.start(true) ensure $logger.close end end