cucumber 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ module Cucumber
2
+ module WireSupport
3
+ class Configuration
4
+ attr_reader :host, :port
5
+
6
+ def initialize(wire_file)
7
+ params = YAML.load_file(wire_file)
8
+ @host = params['host']
9
+ @port = params['port']
10
+ @timeouts = params['timeout'] || {}
11
+ end
12
+
13
+ def timeout(message = nil)
14
+ return @timeouts[message.to_s] || 3
15
+ end
16
+ end
17
+ end
18
+ end
@@ -4,33 +4,35 @@ require 'cucumber/wire_support/wire_protocol'
4
4
  module Cucumber
5
5
  module WireSupport
6
6
  class Connection
7
+ class ConnectionError < StandardError; end
8
+
7
9
  include WireProtocol
8
10
 
9
11
  def initialize(config)
10
- @host, @port = config['host'], config['port']
12
+ @config = config
11
13
  end
12
14
 
13
- def call_remote(response_handler, message, params)
14
- timeout = 3
15
+ def call_remote(request_handler, message, params)
15
16
  packet = WirePacket.new(message, params)
16
17
 
17
18
  begin
18
- send_data_to_socket(packet.to_json, timeout)
19
- response = fetch_data_from_socket(timeout)
20
- response.handle_with(response_handler)
21
- rescue Timeout::Error
22
- raise "Timed out calling server with message #{message}"
19
+ send_data_to_socket(packet.to_json)
20
+ response = fetch_data_from_socket(@config.timeout(message))
21
+ response.handle_with(request_handler)
22
+ rescue Timeout::Error => e
23
+ backtrace = e.backtrace ; backtrace.shift # because Timeout puts some wierd stuff in there
24
+ raise Timeout::Error, "Timed out calling wire server with message '#{message}'", backtrace
23
25
  end
24
26
  end
25
27
 
26
28
  def exception(params)
27
- WireException.new(params, @host, @port)
29
+ WireException.new(params, @config.host, @config.port)
28
30
  end
29
31
 
30
32
  private
31
33
 
32
- def send_data_to_socket(data, timeout)
33
- Timeout.timeout(timeout) { socket.puts(data) }
34
+ def send_data_to_socket(data)
35
+ Timeout.timeout(@config.timeout) { socket.puts(data) }
34
36
  end
35
37
 
36
38
  def fetch_data_from_socket(timeout)
@@ -39,7 +41,9 @@ module Cucumber
39
41
  end
40
42
 
41
43
  def socket
42
- @socket ||= TCPSocket.new(@host, @port)
44
+ @socket ||= TCPSocket.new(@config.host, @config.port)
45
+ rescue Errno::ECONNREFUSED => exception
46
+ raise(ConnectionError, "Unable to contact the wire server at #{@config.host}:#{@config.port}. Is it up?")
43
47
  end
44
48
  end
45
49
  end
@@ -1,19 +1,29 @@
1
1
  module Cucumber
2
2
  module WireSupport
3
3
  class RequestHandler
4
- def initialize(connection, message, &block)
4
+ def initialize(connection)
5
5
  @connection = connection
6
- @message = message
7
- instance_eval(&block) if block
6
+ @message = underscore(self.class.name.split('::').last)
8
7
  end
9
8
 
10
- def execute(request_params)
9
+ def execute(request_params = nil)
11
10
  @connection.call_remote(self, @message, request_params)
12
11
  end
13
12
 
14
13
  def handle_fail(params)
15
14
  raise @connection.exception(params)
16
15
  end
16
+
17
+ private
18
+
19
+ # Props to Rails
20
+ def underscore(camel_cased_word)
21
+ camel_cased_word.to_s.gsub(/::/, '/').
22
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
23
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
24
+ tr("-", "_").
25
+ downcase
26
+ end
17
27
  end
18
28
  end
19
29
  end
@@ -8,6 +8,7 @@ EOM
8
8
  exit(1)
9
9
  end
10
10
  require 'cucumber/wire_support/connection'
11
+ require 'cucumber/wire_support/configuration'
11
12
  require 'cucumber/wire_support/wire_packet'
12
13
  require 'cucumber/wire_support/wire_exception'
13
14
  require 'cucumber/wire_support/wire_step_definition'
@@ -15,19 +16,11 @@ require 'cucumber/wire_support/wire_step_definition'
15
16
  module Cucumber
16
17
  module WireSupport
17
18
 
18
- # The wire-protocol (lanugage independent) implementation of the programming language API.
19
+ # The wire-protocol (lanugage independent) implementation of the programming
20
+ # language API.
19
21
  class WireLanguage
20
22
  include LanguageSupport::LanguageMethods
21
-
22
- def load_code_file(wire_file)
23
- config = YAML.load_file(wire_file)
24
- @connections << Connection.new(config)
25
- end
26
-
27
- def step_matches(step_name, formatted_step_name)
28
- @connections.map{ |remote| remote.step_matches(step_name, formatted_step_name)}.flatten
29
- end
30
-
23
+
31
24
  def initialize(step_mother)
32
25
  @connections = []
33
26
  end
@@ -35,6 +28,11 @@ module Cucumber
35
28
  def alias_adverbs(adverbs)
36
29
  end
37
30
 
31
+ def load_code_file(wire_file)
32
+ config = Configuration.new(wire_file)
33
+ @connections << Connection.new(config)
34
+ end
35
+
38
36
  def snippet_text(step_keyword, step_name, multiline_arg_class)
39
37
  snippets = @connections.map do |remote|
40
38
  remote.snippet_text(step_keyword, step_name, multiline_arg_class.to_s)
@@ -42,6 +40,10 @@ module Cucumber
42
40
  snippets.flatten.join("\n")
43
41
  end
44
42
 
43
+ def step_matches(step_name, formatted_step_name)
44
+ @connections.map{ |remote| remote.step_matches(step_name, formatted_step_name)}.flatten
45
+ end
46
+
45
47
  protected
46
48
 
47
49
  def begin_scenario(scenario)
@@ -51,12 +53,6 @@ module Cucumber
51
53
  def end_scenario
52
54
  @connections.each { |remote| remote.end_scenario }
53
55
  end
54
-
55
- private
56
-
57
- def step_definitions
58
- @step_definitions ||= {}
59
- end
60
56
  end
61
57
  end
62
58
  end
@@ -1,108 +1,44 @@
1
1
  require 'cucumber/step_argument'
2
- require 'cucumber/wire_support/request_handler'
2
+ require 'cucumber/wire_support/wire_protocol/requests'
3
3
 
4
4
  module Cucumber
5
5
  module WireSupport
6
6
  module WireProtocol
7
7
  def step_matches(name_to_match, name_to_report)
8
- @name_to_match, @name_to_report = name_to_match, name_to_report
9
- make_request(:step_matches, :name_to_match => name_to_match) do
10
- def handle_step_matches(params)
11
- params.map do |raw_step_match|
12
- step_definition = WireStepDefinition.new(@connection, raw_step_match)
13
- step_args = raw_step_match['args'].map do |raw_arg|
14
- StepArgument.new(raw_arg['val'], raw_arg['pos'])
15
- end
16
- @connection.step_match(step_definition, step_args) # convoluted!
17
- end
18
- end
19
- end
8
+ handler = Requests::StepMatches.new(self)
9
+ handler.execute(name_to_match, name_to_report)
20
10
  end
21
11
 
22
- def step_match(step_definition, step_args)
23
- StepMatch.new(step_definition, @name_to_match, @name_to_report, step_args)
24
- end
25
-
26
12
  def snippet_text(step_keyword, step_name, multiline_arg_class_name)
27
- request_params = { :step_keyword => step_keyword, :step_name => step_name, :multiline_arg_class => multiline_arg_class_name }
28
-
29
- make_request(:snippet_text, request_params) do
30
- def handle_snippet_text(text)
31
- text
32
- end
33
- end
13
+ handler = Requests::SnippetText.new(self)
14
+ handler.execute(step_keyword, step_name, multiline_arg_class_name)
34
15
  end
35
16
 
36
17
  def invoke(step_definition_id, args)
37
- request_params = { :id => step_definition_id, :args => args }
38
-
39
- make_request(:invoke, request_params) do
40
- def handle_success(params)
41
- end
42
-
43
- def handle_pending(message)
44
- raise Pending, message || "TODO"
45
- end
46
-
47
- def handle_diff(tables)
48
- table1 = Ast::Table.new(tables[0])
49
- table2 = Ast::Table.new(tables[1])
50
- begin
51
- table1.diff!(table2)
52
- rescue Cucumber::Ast::Table::Different
53
- @connection.diff_failed
54
- end
55
- @connection.diff_ok
56
- end
57
-
58
- def handle_step_failed(params)
59
- handle_fail(params)
60
- end
61
- end
18
+ handler = Requests::Invoke.new(self)
19
+ handler.execute(step_definition_id, args)
62
20
  end
63
21
 
64
22
  def diff_failed
65
- make_request(:diff_failed) do
66
- def handle_success(params)
67
- end
68
-
69
- def handle_step_failed(params)
70
- handle_fail(params)
71
- end
72
- end
23
+ handler = Requests::DiffFailed.new(self)
24
+ handler.execute
73
25
  end
74
26
 
75
27
  def diff_ok
76
- make_request(:diff_ok) do
77
- def handle_success(params)
78
- end
79
-
80
- def handle_step_failed(params)
81
- handle_fail(params)
82
- end
83
- end
28
+ handler = Requests::DiffOk.new(self)
29
+ handler.execute
84
30
  end
85
31
 
86
32
  def begin_scenario(scenario)
87
- make_request(:begin_scenario) do
88
- def handle_success(params)
89
- end
90
- end
33
+ handler = Requests::BeginScenario.new(self)
34
+ handler.execute(scenario)
91
35
  end
92
36
 
93
37
  def end_scenario
94
- make_request(:end_scenario) do
95
- def handle_success(params)
96
- end
97
- end
38
+ handler = Requests::EndScenario.new(self)
39
+ handler.execute
98
40
  end
99
41
 
100
- private
101
-
102
- def make_request(request_message, params = nil, &block)
103
- handler = RequestHandler.new(self, request_message, &block)
104
- handler.execute(params)
105
- end
106
42
  end
107
43
  end
108
44
  end
@@ -0,0 +1,113 @@
1
+ require 'cucumber/wire_support/request_handler'
2
+ module Cucumber
3
+ module WireSupport
4
+ module WireProtocol
5
+ module Requests
6
+ class StepMatches < RequestHandler
7
+ def execute(name_to_match, name_to_report)
8
+ @name_to_match, @name_to_report = name_to_match, name_to_report
9
+ request_params = {
10
+ :name_to_match => name_to_match
11
+ }
12
+ super(request_params)
13
+ end
14
+
15
+ def handle_step_matches(params)
16
+ params.map do |raw_step_match|
17
+ step_definition = WireStepDefinition.new(@connection, raw_step_match)
18
+ step_args = raw_step_match['args'].map do |raw_arg|
19
+ StepArgument.new(raw_arg['val'], raw_arg['pos'])
20
+ end
21
+ step_match(step_definition, step_args)
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def step_match(step_definition, step_args)
28
+ StepMatch.new(step_definition, @name_to_match, @name_to_report, step_args)
29
+ end
30
+ end
31
+
32
+ class SnippetText < RequestHandler
33
+ def execute(step_keyword, step_name, multiline_arg_class_name)
34
+ request_params = {
35
+ :step_keyword => step_keyword,
36
+ :step_name => step_name,
37
+ :multiline_arg_class => multiline_arg_class_name
38
+ }
39
+ super(request_params)
40
+ end
41
+
42
+ def handle_snippet_text(text)
43
+ text
44
+ end
45
+ end
46
+
47
+ class Invoke < RequestHandler
48
+ def execute(step_definition_id, args)
49
+ request_params = {
50
+ :id => step_definition_id,
51
+ :args => args
52
+ }
53
+ super(request_params)
54
+ end
55
+
56
+ def handle_success(params)
57
+ end
58
+
59
+ def handle_pending(message)
60
+ raise Pending, message || "TODO"
61
+ end
62
+
63
+ def handle_diff(tables)
64
+ table1 = Ast::Table.new(tables[0])
65
+ table2 = Ast::Table.new(tables[1])
66
+ begin
67
+ table1.diff!(table2)
68
+ rescue Cucumber::Ast::Table::Different
69
+ @connection.diff_failed
70
+ end
71
+ @connection.diff_ok
72
+ end
73
+
74
+ def handle_step_failed(params)
75
+ handle_fail(params)
76
+ end
77
+ end
78
+
79
+ class DiffFailed < RequestHandler
80
+ def handle_success(params)
81
+ end
82
+
83
+ def handle_step_failed(params)
84
+ handle_fail(params)
85
+ end
86
+ end
87
+
88
+ class DiffOk < RequestHandler
89
+ def handle_success(params)
90
+ end
91
+
92
+ def handle_step_failed(params)
93
+ handle_fail(params)
94
+ end
95
+ end
96
+
97
+ class BeginScenario < RequestHandler
98
+ def execute(scenario)
99
+ super(nil) # not passing the scenario yet
100
+ end
101
+
102
+ def handle_success(params)
103
+ end
104
+ end
105
+
106
+ class EndScenario < RequestHandler
107
+ def handle_success(params)
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -21,6 +21,7 @@ module Cucumber
21
21
  before(:each) do
22
22
  @out = StringIO.new
23
23
  @formatter = Html.new(step_mother, @out, {})
24
+ step_mother.visitor = @formatter
24
25
  end
25
26
 
26
27
  it "should not raise an error when visiting a blank feature name" do
@@ -205,6 +206,19 @@ module Cucumber
205
206
  it { @doc.should_not have_css_node('.feature .scenario .step.failed', //) }
206
207
  it { @doc.should have_css_node('.feature .scenario .step.undefined', /yay/) }
207
208
  end
209
+
210
+ describe "with a step that embeds a snapshot" do
211
+ define_steps do
212
+ Given(/snap/) { embed('snapshot.jpeg', 'image/jpeg') }
213
+ end
214
+
215
+ define_feature(<<-FEATURE)
216
+ Scenario:
217
+ Given snap
218
+ FEATURE
219
+
220
+ it { @doc.css('.embed img').first.attributes['src'].to_s.should == "snapshot.jpeg" }
221
+ end
208
222
 
209
223
  end
210
224
  end
@@ -0,0 +1,34 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require 'cucumber/wire_support/wire_language'
3
+ require 'tempfile'
4
+
5
+ module Cucumber
6
+ module WireSupport
7
+ describe Configuration do
8
+ it "should read the hostname / port from the file" do
9
+ wire_file = Tempfile.new('wire')
10
+ wire_file << %q{
11
+ host: localhost
12
+ port: 54321
13
+ }
14
+ wire_file.close
15
+ config = Configuration.new(wire_file.path)
16
+ config.host.should == 'localhost'
17
+ config.port.should == 54321
18
+ end
19
+
20
+ it "should read the timeout for a specific message" do
21
+ wire_file = Tempfile.new('wire')
22
+ wire_file << %q{
23
+ host: localhost
24
+ port: 54321
25
+ timeout:
26
+ invoke: 99
27
+ }
28
+ wire_file.close
29
+ config = Configuration.new(wire_file.path)
30
+ config.timeout(:invoke).should == 99
31
+ end
32
+ end
33
+ end
34
+ end