cucumber-wire 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +1 -0
- data/.travis.yml +18 -0
- data/Gemfile +20 -0
- data/README.md +1 -0
- data/Rakefile +13 -0
- data/cucumber-wire.gemspec +28 -0
- data/features/erb_configuration.feature +54 -0
- data/features/handle_unexpected_response.feature +29 -0
- data/features/invoke_message.feature +212 -0
- data/features/readme.md +26 -0
- data/features/snippets_message.feature +47 -0
- data/features/step_definitions/aruba_steps.rb +1 -0
- data/features/step_definitions/wire_steps.rb +58 -0
- data/features/step_matches_message.feature +79 -0
- data/features/support/fake_wire_server.rb +80 -0
- data/features/table_diffing.feature +124 -0
- data/features/tags.feature +86 -0
- data/features/timeouts.feature +63 -0
- data/lib/cucumber/wire.rb +5 -0
- data/lib/cucumber/wire/add_hooks_filter.rb +25 -0
- data/lib/cucumber/wire/configuration.rb +38 -0
- data/lib/cucumber/wire/connection.rb +63 -0
- data/lib/cucumber/wire/connections.rb +50 -0
- data/lib/cucumber/wire/data_packet.rb +34 -0
- data/lib/cucumber/wire/exception.rb +32 -0
- data/lib/cucumber/wire/plugin.rb +32 -0
- data/lib/cucumber/wire/protocol.rb +43 -0
- data/lib/cucumber/wire/protocol/requests.rb +128 -0
- data/lib/cucumber/wire/request_handler.rb +32 -0
- data/lib/cucumber/wire/snippet.rb +35 -0
- data/lib/cucumber/wire/step_definition.rb +21 -0
- data/lib/cucumber/wire/version +1 -0
- data/spec/cucumber/wire/configuration_spec.rb +63 -0
- data/spec/cucumber/wire/connection_spec.rb +64 -0
- data/spec/cucumber/wire/connections_spec.rb +23 -0
- data/spec/cucumber/wire/data_packet_spec.rb +43 -0
- data/spec/cucumber/wire/exception_spec.rb +50 -0
- metadata +157 -0
checksums.yaml
ADDED
@@ -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
|
data/.travis.yml
ADDED
@@ -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
|
data/README.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Work in progress: See https://github.com/cucumber/cucumber-ruby/pull/878
|
data/Rakefile
ADDED
@@ -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 |
|
data/features/readme.md
ADDED
@@ -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
|
+
"""
|