cucumber 0.5.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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