cucumber-wire 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +18 -0
  4. data/Gemfile +20 -0
  5. data/README.md +1 -0
  6. data/Rakefile +13 -0
  7. data/cucumber-wire.gemspec +28 -0
  8. data/features/erb_configuration.feature +54 -0
  9. data/features/handle_unexpected_response.feature +29 -0
  10. data/features/invoke_message.feature +212 -0
  11. data/features/readme.md +26 -0
  12. data/features/snippets_message.feature +47 -0
  13. data/features/step_definitions/aruba_steps.rb +1 -0
  14. data/features/step_definitions/wire_steps.rb +58 -0
  15. data/features/step_matches_message.feature +79 -0
  16. data/features/support/fake_wire_server.rb +80 -0
  17. data/features/table_diffing.feature +124 -0
  18. data/features/tags.feature +86 -0
  19. data/features/timeouts.feature +63 -0
  20. data/lib/cucumber/wire.rb +5 -0
  21. data/lib/cucumber/wire/add_hooks_filter.rb +25 -0
  22. data/lib/cucumber/wire/configuration.rb +38 -0
  23. data/lib/cucumber/wire/connection.rb +63 -0
  24. data/lib/cucumber/wire/connections.rb +50 -0
  25. data/lib/cucumber/wire/data_packet.rb +34 -0
  26. data/lib/cucumber/wire/exception.rb +32 -0
  27. data/lib/cucumber/wire/plugin.rb +32 -0
  28. data/lib/cucumber/wire/protocol.rb +43 -0
  29. data/lib/cucumber/wire/protocol/requests.rb +128 -0
  30. data/lib/cucumber/wire/request_handler.rb +32 -0
  31. data/lib/cucumber/wire/snippet.rb +35 -0
  32. data/lib/cucumber/wire/step_definition.rb +21 -0
  33. data/lib/cucumber/wire/version +1 -0
  34. data/spec/cucumber/wire/configuration_spec.rb +63 -0
  35. data/spec/cucumber/wire/connection_spec.rb +64 -0
  36. data/spec/cucumber/wire/connections_spec.rb +23 -0
  37. data/spec/cucumber/wire/data_packet_spec.rb +43 -0
  38. data/spec/cucumber/wire/exception_spec.rb +50 -0
  39. metadata +157 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 193ced89d633c8b78eee1a626af39e9f69a2dbc5
4
+ data.tar.gz: 42c38717dab358471f86f3f1085c186c2e9df3a6
5
+ SHA512:
6
+ metadata.gz: d48ac504abae09629fd5baca0dd4b1ef8488623b5da662a1cdfc7b2e8a1808420845f51d1a990def3ee625f211834236814d21f6aa9311d810a0b406031ed343
7
+ data.tar.gz: b131fcc0318fd1cadec22641e8fac0ab9575db479711a708508c2282b7ba73c2df7859ee3653285364f66daaccf97382dae3dfabc0bf1be1ca306f89ef9a742c
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,18 @@
1
+ rvm:
2
+ - 2.2
3
+ - 2.1
4
+ - 2.0
5
+ - 1.9.3
6
+ - jruby-1.7.12
7
+
8
+ # whitelist
9
+ branches:
10
+ only:
11
+ - master
12
+
13
+ notifications:
14
+ email:
15
+ - cukes-devs@googlegroups.com
16
+ webhooks:
17
+ urls: # gitter
18
+ - https://webhooks.gitter.im/e/dc010332f9d40fcc21c4
data/Gemfile ADDED
@@ -0,0 +1,20 @@
1
+ gemspec
2
+
3
+ source "https://rubygems.org"
4
+ unless ENV['CUCUMBER_USE_RELEASED_GEMS']
5
+ # cucumber gem
6
+ cucumber_path = File.expand_path("../../cucumber-ruby", __FILE__)
7
+ if File.exist?(cucumber_path) && !ENV['CUCUMBER_USE_GIT']
8
+ gem "cucumber", path: cucumber_path, branch: "remove-wire-protocol-to-plugin"
9
+ else
10
+ gem "cucumber", :git => "git://github.com/cucumber/cucumber-ruby.git", branch: "remove-wire-protocol-to-plugin"
11
+ end
12
+
13
+ # cucumber-core gem
14
+ core_path = File.expand_path("../../cucumber-ruby-core", __FILE__)
15
+ if File.exist?(core_path) && !ENV['CUCUMBER_USE_GIT_CORE']
16
+ gem "cucumber-core", path: core_path
17
+ else
18
+ gem 'cucumber-core', :git => "git://github.com/cucumber/cucumber-ruby-core.git"
19
+ end
20
+ end
@@ -0,0 +1 @@
1
+ Work in progress: See https://github.com/cucumber/cucumber-ruby/pull/878
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler::GemHelper.install_tasks
4
+
5
+ task default: [:unit_tests, :acceptance_tests]
6
+
7
+ task :unit_tests do
8
+ sh "bundle exec rspec"
9
+ end
10
+
11
+ task :acceptance_tests do
12
+ sh "bundle exec cucumber"
13
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'cucumber-wire'
6
+ s.version = File.read(File.dirname(__FILE__) + "/lib/cucumber/wire/version")
7
+ s.authors = ["Matt Wynne"]
8
+ s.description = "Wire protocol for Cucumber"
9
+ s.summary = "cucumber-wire-#{s.version}"
10
+ s.email = 'cukes@googlegroups.com'
11
+ s.homepage = "http://cucumber.io"
12
+ s.platform = Gem::Platform::RUBY
13
+ s.license = "MIT"
14
+ s.required_ruby_version = ">= 1.9.3"
15
+
16
+ s.add_development_dependency 'cucumber', '~> 2.1.0'
17
+
18
+ s.add_development_dependency 'bundler', '>= 1.3.5'
19
+ s.add_development_dependency 'rake', '>= 0.9.2'
20
+ s.add_development_dependency 'rspec', '~> 3'
21
+ s.add_development_dependency 'aruba', '~> 0'
22
+
23
+ s.rubygems_version = ">= 1.6.1"
24
+ s.files = `git ls-files`.split("\n").reject {|path| path =~ /\.gitignore$/ }
25
+ s.test_files = `git ls-files -- spec/*`.split("\n")
26
+ s.rdoc_options = ["--charset=UTF-8"]
27
+ s.require_path = "lib"
28
+ end
@@ -0,0 +1,54 @@
1
+ Feature: ERB configuration
2
+
3
+ As a developer on server with multiple users
4
+ I want to be able to configure which port my wire server runs on
5
+ So that I can avoid port conflicts
6
+
7
+ Background:
8
+ Given a file named "features/wired.feature" with:
9
+ """
10
+ Feature: High strung
11
+ Scenario: Wired
12
+ Given we're all wired
13
+
14
+ """
15
+
16
+ Scenario: ERB is used in the wire file which references an environment variable that is not set
17
+ Given a file named "features/step_definitions/server.wire" with:
18
+ """
19
+ host: localhost
20
+ port: <%= ENV['PORT'] || 12345 %>
21
+ """
22
+ And there is a wire server running on port 12345 which understands the following protocol:
23
+ | request | response |
24
+ | ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[]] |
25
+ When I run `cucumber --dry-run --no-snippets -f progress`
26
+ Then it should pass with:
27
+ """
28
+ U
29
+
30
+ 1 scenario (1 undefined)
31
+ 1 step (1 undefined)
32
+
33
+ """
34
+
35
+
36
+ Scenario: ERB is used in the wire file which references an environment variable
37
+ Given I have environment variable PORT set to "16816"
38
+ And a file named "features/step_definitions/server.wire" with:
39
+ """
40
+ host: localhost
41
+ port: <%= ENV['PORT'] || 12345 %>
42
+ """
43
+ And there is a wire server running on port 16816 which understands the following protocol:
44
+ | request | response |
45
+ | ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[]] |
46
+ When I run `cucumber --dry-run --no-snippets -f progress`
47
+ Then it should pass with:
48
+ """
49
+ U
50
+
51
+ 1 scenario (1 undefined)
52
+ 1 step (1 undefined)
53
+
54
+ """
@@ -0,0 +1,29 @@
1
+ Feature: Handle unexpected response
2
+
3
+ When the server sends us back a message we don't understand, this is how Cucumber will behave.
4
+
5
+ Background:
6
+ Given a file named "features/wired.feature" with:
7
+ """
8
+ Feature: High strung
9
+ Scenario: Wired
10
+ Given we're all wired
11
+
12
+ """
13
+ And a file named "features/step_definitions/some_remote_place.wire" with:
14
+ """
15
+ host: localhost
16
+ port: 54321
17
+
18
+ """
19
+
20
+ Scenario: Unexpected response
21
+ Given there is a wire server running on port 54321 which understands the following protocol:
22
+ | request | response |
23
+ | ["begin_scenario"] | ["yikes"] |
24
+ | ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[]}]] |
25
+ When I run `cucumber -f pretty`
26
+ Then the output should contain:
27
+ """
28
+ undefined method `handle_yikes'
29
+ """
@@ -0,0 +1,212 @@
1
+ Feature: Invoke message
2
+
3
+ Assuming a StepMatch was returned for a given step name, when it's time to
4
+ invoke that step definition, Cucumber will send an invoke message.
5
+
6
+ The invoke message contains the ID of the step definition, as returned by
7
+ the wire server in response to the the step_matches call, along with the
8
+ arguments that were parsed from the step name during the same step_matches
9
+ call.
10
+
11
+ The wire server will normally reply one of the following:
12
+
13
+ * `success`
14
+ * `fail`
15
+ * `pending` - optionally takes a message argument
16
+
17
+ This isn't quite the whole story: see also table_diffing.feature
18
+
19
+ Background:
20
+ Given a file named "features/wired.feature" with:
21
+ """
22
+ Feature: High strung
23
+ Scenario: Wired
24
+ Given we're all wired
25
+
26
+ """
27
+ And a file named "features/step_definitions/some_remote_place.wire" with:
28
+ """
29
+ host: localhost
30
+ port: 54321
31
+
32
+ """
33
+
34
+
35
+ @spawn
36
+ Scenario: Invoke a step definition which is pending
37
+ Given there is a wire server running on port 54321 which understands the following protocol:
38
+ | request | response |
39
+ | ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[]}]] |
40
+ | ["begin_scenario"] | ["success"] |
41
+ | ["invoke",{"id":"1","args":[]}] | ["pending", "I'll do it later"] |
42
+ | ["end_scenario"] | ["success"] |
43
+ When I run `cucumber -f pretty -q`
44
+ And it should pass with exactly:
45
+ """
46
+ Feature: High strung
47
+
48
+ Scenario: Wired
49
+ Given we're all wired
50
+ I'll do it later (Cucumber::Pending)
51
+ features/wired.feature:3:in `Given we're all wired'
52
+
53
+ 1 scenario (1 pending)
54
+ 1 step (1 pending)
55
+
56
+ """
57
+
58
+ Scenario: Invoke a step definition which passes
59
+ Given there is a wire server running on port 54321 which understands the following protocol:
60
+ | request | response |
61
+ | ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[]}]] |
62
+ | ["begin_scenario"] | ["success"] |
63
+ | ["invoke",{"id":"1","args":[]}] | ["success"] |
64
+ | ["end_scenario"] | ["success"] |
65
+ When I run `cucumber -f progress`
66
+ And it should pass with:
67
+ """
68
+ .
69
+
70
+ 1 scenario (1 passed)
71
+ 1 step (1 passed)
72
+
73
+ """
74
+
75
+ @spawn
76
+ Scenario: Invoke a step definition which fails
77
+
78
+ If an invoked step definition fails, it can return details of the exception
79
+ in the reply to invoke. This causes a Cucumber::WireSupport::WireException to be
80
+ raised.
81
+
82
+ Valid arguments are:
83
+
84
+ - `message` (mandatory)
85
+ - `exception`
86
+ - `backtrace`
87
+
88
+ See the specs for Cucumber::WireSupport::WireException for more details
89
+
90
+ Given there is a wire server running on port 54321 which understands the following protocol:
91
+ | request | response |
92
+ | ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[]}]] |
93
+ | ["begin_scenario"] | ["success"] |
94
+ | ["invoke",{"id":"1","args":[]}] | ["fail",{"message":"The wires are down", "exception":"Some.Foreign.ExceptionType"}] |
95
+ | ["end_scenario"] | ["success"] |
96
+ When I run `cucumber -f progress`
97
+ Then the stderr should not contain anything
98
+ And it should fail with:
99
+ """
100
+ F
101
+
102
+ (::) failed steps (::)
103
+
104
+ The wires are down (Some.Foreign.ExceptionType from localhost:54321)
105
+ features/wired.feature:3:in `Given we're all wired'
106
+
107
+ Failing Scenarios:
108
+ cucumber features/wired.feature:2 # Scenario: Wired
109
+
110
+ 1 scenario (1 failed)
111
+ 1 step (1 failed)
112
+
113
+ """
114
+
115
+ Scenario: Invoke a step definition which takes string arguments (and passes)
116
+
117
+ If the step definition at the end of the wire captures arguments, these are
118
+ communicated back to Cucumber in the `step_matches` message.
119
+
120
+ Cucumber expects these StepArguments to be returned in the StepMatch. The keys
121
+ have the following meanings:
122
+
123
+ - `val` - the value of the string captured for that argument from the step
124
+ name passed in step_matches
125
+ - `pos` - the position within the step name that the argument was matched
126
+ (used for formatter highlighting)
127
+
128
+ The argument values are then sent back by Cucumber in the `invoke` message.
129
+
130
+ Given there is a wire server running on port 54321 which understands the following protocol:
131
+ | request | response |
132
+ | ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[{"val":"wired", "pos":10}]}]] |
133
+ | ["begin_scenario"] | ["success"] |
134
+ | ["invoke",{"id":"1","args":["wired"]}] | ["success"] |
135
+ | ["end_scenario"] | ["success"] |
136
+ When I run `cucumber -f progress`
137
+ Then the stderr should not contain anything
138
+ And it should pass with:
139
+ """
140
+ .
141
+
142
+ 1 scenario (1 passed)
143
+ 1 step (1 passed)
144
+
145
+ """
146
+
147
+ Scenario: Invoke a step definition which takes regular and table arguments (and passes)
148
+
149
+ If the step has a multiline table argument, it will be passed with the
150
+ invoke message as an array of array of strings.
151
+
152
+ In this scenario our step definition takes two arguments - one
153
+ captures the "we're" and the other takes the table.
154
+
155
+ Given a file named "features/wired_on_tables.feature" with:
156
+ """
157
+ Feature: High strung
158
+ Scenario: Wired and more
159
+ Given we're all:
160
+ | wired |
161
+ | high |
162
+ | happy |
163
+ """
164
+ And there is a wire server running on port 54321 which understands the following protocol:
165
+ | request | response |
166
+ | ["step_matches",{"name_to_match":"we're all:"}] | ["success",[{"id":"1", "args":[{"val":"we're", "pos":0}]}]] |
167
+ | ["begin_scenario"] | ["success"] |
168
+ | ["invoke",{"id":"1","args":["we're",[["wired"],["high"],["happy"]]]}] | ["success"] |
169
+ | ["end_scenario"] | ["success"] |
170
+ When I run `cucumber -f progress features/wired_on_tables.feature`
171
+ Then the stderr should not contain anything
172
+ And it should pass with:
173
+ """
174
+ .
175
+
176
+ 1 scenario (1 passed)
177
+ 1 step (1 passed)
178
+
179
+ """
180
+
181
+ Scenario: Invoke a scenario outline step
182
+ Given a file named "features/wired_in_an_outline.feature" with:
183
+ """
184
+ Feature:
185
+ Scenario Outline:
186
+ Given we're all <arg>
187
+
188
+ Examples:
189
+ | arg |
190
+ | wired |
191
+ """
192
+ And there is a wire server running on port 54321 which understands the following protocol:
193
+ | request | response |
194
+ | ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[]}]] |
195
+ | ["begin_scenario"] | ["success"] |
196
+ | ["invoke",{"id":"1","args":[]}] | ["success"] |
197
+ | ["end_scenario"] | ["success"] |
198
+ When I run `cucumber -f progress features/wired_in_an_outline.feature`
199
+ Then the stderr should not contain anything
200
+ And it should pass with:
201
+ """
202
+ .
203
+
204
+ 1 scenario (1 passed)
205
+ 1 step (1 passed)
206
+
207
+ """
208
+ And the wire server should have received the following messages:
209
+ | step_matches |
210
+ | begin_scenario |
211
+ | invoke |
212
+ | end_scenario |
@@ -0,0 +1,26 @@
1
+ Cucumber's wire protocol allows step definitions to be
2
+ implemented and invoked on any platform.
3
+
4
+ Communication is over a TCP socket, which Cucumber connects to when it finds
5
+ a definition file with the .wire extension in the step_definitions folder
6
+ (or other load path). Note that these files are rendered with ERB when loaded.
7
+
8
+ A `Wire::DataPacket` flowing in either direction is formatted as a JSON-encoded
9
+ string, with a newline character signaling the end of a packet. See the
10
+ specs for `Cucumber::Wire::DataPacket` for more details.
11
+
12
+ Cucumber sends the following request messages out over the wire:
13
+
14
+ * `step_matches` - Find out whether the wire server has a definition for a step
15
+ * `invoke` - Ask for a step definition to be invoked
16
+ * `begin_scenario` - signals that cucumber is about to execute a scenario
17
+ * `end_scenario` - signals that cucumber has finished executing a scenario
18
+ * `snippet_text` - requests a snippet for an undefined step
19
+
20
+ Every message supports two standard responses:
21
+
22
+ * `success` - expects different arguments (sometimes none at all) depending
23
+ on the request that was sent.
24
+ * `fail` - causes a Cucumber::Wire::Exception to be raised.
25
+
26
+ Some messages support more responses - see individual scenarios for details.
@@ -0,0 +1,47 @@
1
+ Feature: Snippets message
2
+
3
+ If a step doesn't match, Cucumber will ask the wire server to return a snippet of code for a
4
+ step definition.
5
+
6
+ Background:
7
+ Given a file named "features/wired.feature" with:
8
+ """
9
+ Feature: High strung
10
+ Scenario: Wired
11
+ Given we're all wired
12
+
13
+ """
14
+ And a file named "features/step_definitions/some_remote_place.wire" with:
15
+ """
16
+ host: localhost
17
+ port: 54321
18
+
19
+ """
20
+
21
+ @spawn
22
+ Scenario: Wire server returns snippets for a step that didn't match
23
+ Given there is a wire server running on port 54321 which understands the following protocol:
24
+ | request | response |
25
+ | ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[]] |
26
+ | ["snippet_text",{"step_keyword":"Given","multiline_arg_class":"","step_name":"we're all wired"}] | ["success","foo()\n bar;\nbaz"] |
27
+ | ["begin_scenario"] | ["success"] |
28
+ | ["end_scenario"] | ["success"] |
29
+ When I run `cucumber -f pretty`
30
+ Then the stderr should not contain anything
31
+ And it should pass with:
32
+ """
33
+ Feature: High strung
34
+
35
+ Scenario: Wired # features/wired.feature:2
36
+ Given we're all wired # features/wired.feature:3
37
+
38
+ 1 scenario (1 undefined)
39
+ 1 step (1 undefined)
40
+ """
41
+ And the output should contain:
42
+ """
43
+ foo()
44
+ bar;
45
+ baz
46
+
47
+ """