Skip to content

Instantly share code, notes, and snippets.

@graza
Created October 14, 2011 00:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save graza/1285897 to your computer and use it in GitHub Desktop.
Save graza/1285897 to your computer and use it in GitHub Desktop.
EPM Language Support
require 'socket'
require 'cucumber/language_support/language_methods'
require 'cucumber/wire_support/connection'
require 'cucumber/wire_support/wire_protocol'
require 'cucumber/wire_support/wire_packet'
require 'cucumber/wire_support/wire_step_definition'
module Cucumber
module EpmSupport
class EpmLanguage
include LanguageSupport::LanguageMethods
def initialize(step_mother)
@connection = EpmSupport::Connection.new(30)
end
def load_code_file(epm_file)
@connection.load_code_file(epm_file)
end
#def alias_adverbs(adverbs)
#end
def snippet_text(code_keyword, step_name, multiline_arg_class)
@connection.snippet_text(code_keyword, step_name, multiline_arg_class.to_s)
end
def step_matches(step_name, formatted_step_name)
@connection.step_matches(step_name, formatted_step_name)
end
protected
def begin_scenario(scenario)
@connection.begin_scenario(scenario)
@current_scenario = scenario
end
def end_scenario
scenario = @current_scenario
@connection.end_scenario(scenario)
@current_scenario = nil
end
end
module EpmProtocol
def load_code_file(epm_file)
handler = EpmRequests::LoadCodeFile.new(self)
handler.execute(epm_file)
end
module EpmRequests
class LoadCodeFile < WireSupport::RequestHandler
def execute(epm_file)
request_params = {
:epm_file => epm_file
}
super(request_params)
end
end
end
end
class Connection
class ConnectionError < StandardError; end
include WireSupport::WireProtocol
include EpmProtocol
def initialize(timeout)
@timeout = timeout
spawn_server
end
def call_remote(request_handler, message, params)
packet = WireSupport::WirePacket.new(message, params)
begin
send_data_to_socket(packet.to_json)
response = fetch_data_from_socket(@timeout)
response.handle_with(request_handler)
rescue Timeout::Error => e
backtrace = e.backtrace ; backtrace.shift # because Timeout puts some wierd stuff in there
raise Timeout::Error, "Timed out calling wire server with message '#{message}'", backtrace
end
end
def exception(params)
WireException.new(params, '', '')
end
private
def send_data_to_socket(data)
Timeout.timeout(@timeout) { @socket.puts(data) }
end
def fetch_data_from_socket(timeout)
raw_response =
if timeout == :never
@socket.gets
else
Timeout.timeout(timeout) { @socket.gets }
end
WireSupport::WirePacket.parse(raw_response)
end
def spawn_server
@socket, child = Socket.pair(:UNIX, :STREAM, 0)
Process.spawn(
{"SOCKFD" => child.fileno.to_s},
*server_cmd,
{@socket.fileno => :close, :close_others => false}
)
# TODO: add an atExit hook to make sure the child process is shutdown
child.close
end
def server_cmd
epmtestharness = ENV['PATH'].split(/:/).collect do |dir|
eth = File.join(dir, 'epmtestharness')
File.executable?(eth) ? eth : nil
end.compact
raise 'epmtestharness not found' unless epmtestharness
return [
[epmtestharness[0], File.basename(epmtestharness[0])],
File.expand_path("../server.epm", __FILE__)
]
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment