Created
October 14, 2011 00:17
-
-
Save graza/1285897 to your computer and use it in GitHub Desktop.
EPM Language Support
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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