cucumber 2.0.0.rc.4 → 2.0.0.rc.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +74 -52
  3. data/examples/i18n/ht/Rakefile +6 -0
  4. data/examples/i18n/ht/features/adisyon.feature +17 -0
  5. data/examples/i18n/ht/features/divizyon.feature +10 -0
  6. data/examples/i18n/ht/features/step_definitions/kalkilatris_steps.rb +25 -0
  7. data/examples/i18n/ht/lib/kalkilatris.rb +14 -0
  8. data/features/docs/cli/dry_run.feature +43 -0
  9. data/features/docs/cli/strict_mode.feature +24 -1
  10. data/features/docs/defining_steps/nested_steps.feature +49 -0
  11. data/features/docs/exception_in_after_step_hook.feature +1 -1
  12. data/features/docs/exception_in_around_hook.feature +80 -0
  13. data/features/docs/formatters/json_formatter.feature +65 -1
  14. data/features/docs/formatters/junit_formatter.feature +40 -0
  15. data/features/docs/{wire_protocol_erb.feature → wire_protocol/erb_configuration.feature} +2 -2
  16. data/features/docs/wire_protocol/handle_unexpected_response.feature +30 -0
  17. data/features/docs/wire_protocol/invoke_message.feature +216 -0
  18. data/features/docs/wire_protocol/readme.md +26 -0
  19. data/features/docs/wire_protocol/snippets_message.feature +51 -0
  20. data/features/docs/wire_protocol/step_matches_message.feature +81 -0
  21. data/features/docs/{wire_protocol_table_diffing.feature → wire_protocol/table_diffing.feature} +1 -0
  22. data/features/docs/{wire_protocol_tags.feature → wire_protocol/tags.feature} +1 -0
  23. data/features/docs/{wire_protocol_timeouts.feature → wire_protocol/timeouts.feature} +1 -0
  24. data/features/docs/work_in_progress.feature +1 -1
  25. data/features/docs/writing_support_code/around_hooks.feature +31 -0
  26. data/features/docs/writing_support_code/before_hook.feature +7 -3
  27. data/features/docs/writing_support_code/tagged_hooks.feature +44 -6
  28. data/features/lib/step_definitions/wire_steps.rb +18 -1
  29. data/features/lib/support/fake_wire_server.rb +10 -7
  30. data/lib/cucumber.rb +1 -3
  31. data/lib/cucumber/cli/options.rb +7 -0
  32. data/lib/cucumber/encoding.rb +5 -0
  33. data/lib/cucumber/errors.rb +8 -0
  34. data/lib/cucumber/filters/prepare_world.rb +13 -5
  35. data/lib/cucumber/formatter/console.rb +1 -1
  36. data/lib/cucumber/formatter/gherkin_formatter_adapter.rb +9 -6
  37. data/lib/cucumber/formatter/junit.rb +95 -0
  38. data/lib/cucumber/formatter/legacy_api/adapter.rb +39 -3
  39. data/lib/cucumber/platform.rb +1 -1
  40. data/lib/cucumber/project_initializer.rb +43 -0
  41. data/lib/cucumber/rb_support/rb_step_definition.rb +11 -2
  42. data/lib/cucumber/rb_support/rb_world.rb +2 -2
  43. data/lib/cucumber/rb_support/snippet.rb +1 -1
  44. data/lib/cucumber/rspec/doubles.rb +1 -1
  45. data/lib/cucumber/running_test_case.rb +115 -0
  46. data/lib/cucumber/runtime.rb +5 -1
  47. data/lib/cucumber/runtime/for_programming_languages.rb +2 -2
  48. data/lib/cucumber/runtime/support_code.rb +18 -8
  49. data/spec/cucumber/formatter/junit_spec.rb +212 -156
  50. data/spec/cucumber/formatter/legacy_api/adapter_spec.rb +89 -1
  51. data/spec/cucumber/formatter/pretty_spec.rb +13 -0
  52. data/spec/cucumber/project_initializer_spec.rb +87 -0
  53. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +21 -3
  54. data/spec/cucumber/rb_support/snippet_spec.rb +6 -6
  55. data/spec/cucumber/running_test_case_spec.rb +83 -0
  56. data/spec/spec_helper.rb +1 -4
  57. metadata +35 -18
  58. data/bin/cuke +0 -60
  59. data/features/docs/report_called_undefined_steps.feature +0 -57
  60. data/features/docs/wire_protocol.feature +0 -337
  61. data/lib/cucumber/ast/facade.rb +0 -117
@@ -127,3 +127,52 @@ Feature: Nested Steps
127
127
  1 scenario (1 failed)
128
128
  1 step (1 failed)
129
129
  """
130
+
131
+ Scenario: Undefined nested step
132
+ Given a file named "features/call_undefined_step_from_step_def.feature" with:
133
+ """
134
+ Feature: Calling undefined step
135
+
136
+ Scenario: Call directly
137
+ Given a step that calls an undefined step
138
+
139
+ Scenario: Call via another
140
+ Given a step that calls a step that calls an undefined step
141
+ """
142
+ And a file named "features/step_definitions/steps.rb" with:
143
+ """
144
+ Given /^a step that calls an undefined step$/ do
145
+ step 'this does not exist'
146
+ end
147
+
148
+ Given /^a step that calls a step that calls an undefined step$/ do
149
+ step 'a step that calls an undefined step'
150
+ end
151
+ """
152
+ When I run `cucumber -q features/call_undefined_step_from_step_def.feature`
153
+ Then it should fail with exactly:
154
+ """
155
+ Feature: Calling undefined step
156
+
157
+ Scenario: Call directly
158
+ Given a step that calls an undefined step
159
+ Undefined dynamic step: "this does not exist" (Cucumber::UndefinedDynamicStep)
160
+ ./features/step_definitions/steps.rb:2:in `/^a step that calls an undefined step$/'
161
+ features/call_undefined_step_from_step_def.feature:4:in `Given a step that calls an undefined step'
162
+
163
+ Scenario: Call via another
164
+ Given a step that calls a step that calls an undefined step
165
+ Undefined dynamic step: "this does not exist" (Cucumber::UndefinedDynamicStep)
166
+ ./features/step_definitions/steps.rb:2:in `/^a step that calls an undefined step$/'
167
+ ./features/step_definitions/steps.rb:6:in `/^a step that calls a step that calls an undefined step$/'
168
+ features/call_undefined_step_from_step_def.feature:7:in `Given a step that calls a step that calls an undefined step'
169
+
170
+ Failing Scenarios:
171
+ cucumber features/call_undefined_step_from_step_def.feature:3
172
+ cucumber features/call_undefined_step_from_step_def.feature:6
173
+
174
+ 2 scenarios (2 failed)
175
+ 2 steps (2 failed)
176
+ 0m0.012s
177
+
178
+ """
@@ -94,7 +94,7 @@ Feature: Exception in AfterStep Block
94
94
  Given this step passes # features/step_definitions/steps.rb:1
95
95
 
96
96
  Failing Scenarios:
97
- cucumber features/naughty_step_in_scenario_outline.feature:9 # Scenario Outline: Naughty Step, Examples (row 2)
97
+ cucumber features/naughty_step_in_scenario_outline.feature:9 # Scenario Outline: Naughty Step, Examples (#2)
98
98
 
99
99
  4 scenarios (1 failed, 3 passed)
100
100
  4 steps (4 passed)
@@ -0,0 +1,80 @@
1
+ Feature: Exceptions in Around Hooks
2
+
3
+ Around hooks are awkward beasts to handle internally.
4
+
5
+ Right now, if there's an error in your Around hook before you call `block.call`,
6
+ we won't even print the steps for the scenario.
7
+
8
+ This is because that `block.call` invokes all the logic that would tell Cucumber's
9
+ UI about the steps in your scenario. If we never reach that code, we'll never be
10
+ told about them.
11
+
12
+ There's another scenario to consider, where the exception occurs after the steps
13
+ have been run. How would we want to report in that case?
14
+
15
+ Scenario: Exception before the test case is run
16
+ Given the standard step definitions
17
+ And a file named "features/support/env.rb" with:
18
+ """
19
+ Around do |scenario, block|
20
+ fail "this should be reported"
21
+ block.call
22
+ end
23
+ """
24
+ And a file named "features/test.feature" with:
25
+ """
26
+ Feature:
27
+ Scenario:
28
+ Given this step passes
29
+ """
30
+ When I run `cucumber -q`
31
+ Then it should fail with exactly:
32
+ """
33
+ Feature:
34
+
35
+ Scenario:
36
+ this should be reported (RuntimeError)
37
+ ./features/support/env.rb:2:in `Around'
38
+
39
+ Failing Scenarios:
40
+ cucumber features/test.feature:2
41
+
42
+ 1 scenario (1 failed)
43
+ 0 steps
44
+ 0m0.012s
45
+
46
+ """
47
+
48
+ Scenario: Exception after the test case is run
49
+ Given the standard step definitions
50
+ And a file named "features/support/env.rb" with:
51
+ """
52
+ Around do |scenario, block|
53
+ block.call
54
+ fail "this should be reported"
55
+ end
56
+ """
57
+ And a file named "features/test.feature" with:
58
+ """
59
+ Feature:
60
+ Scenario:
61
+ Given this step passes
62
+ """
63
+ When I run `cucumber -q`
64
+ Then it should fail with exactly:
65
+ """
66
+ Feature:
67
+
68
+ Scenario:
69
+ Given this step passes
70
+ this should be reported (RuntimeError)
71
+ ./features/support/env.rb:3:in `Around'
72
+
73
+ Failing Scenarios:
74
+ cucumber features/test.feature:2
75
+
76
+ 1 scenario (1 failed)
77
+ 1 step (1 passed)
78
+ 0m0.012s
79
+
80
+ """
@@ -82,6 +82,14 @@ Feature: JSON output formatter
82
82
  Scenario:
83
83
  Given I embed data directly
84
84
 
85
+ Scenario Outline:
86
+ Given I embed data directly
87
+
88
+ Examples:
89
+ | dummy |
90
+ | 1 |
91
+ | 2 |
92
+
85
93
  """
86
94
  And a file named "features/out_scenario_out_scenario_outline.feature" with:
87
95
  """
@@ -613,7 +621,7 @@ Feature: JSON output formatter
613
621
 
614
622
  @spawn
615
623
  Scenario: embedding data directly
616
- When I run `cucumber -b --format json features/embed_data_directly.feature`
624
+ When I run `cucumber -b --format json -x features/embed_data_directly.feature`
617
625
  Then it should pass with JSON:
618
626
  """
619
627
  [
@@ -652,6 +660,62 @@ Feature: JSON output formatter
652
660
  }
653
661
  }
654
662
  ]
663
+ },
664
+ {
665
+ "keyword": "Scenario Outline",
666
+ "name": "",
667
+ "line": 11,
668
+ "description": "",
669
+ "id": "an-embed-data-directly-feature;;;2",
670
+ "type": "scenario",
671
+ "steps": [
672
+ {
673
+ "keyword": "Given ",
674
+ "name": "I embed data directly",
675
+ "line": 11,
676
+ "embeddings": [
677
+ {
678
+ "mime_type": "mime-type",
679
+ "data": "YWJj"
680
+ }
681
+ ],
682
+ "match": {
683
+ "location": "features/step_definitions/json_steps.rb:10"
684
+ },
685
+ "result": {
686
+ "status": "passed",
687
+ "duration": 1
688
+ }
689
+ }
690
+ ]
691
+ },
692
+ {
693
+ "keyword": "Scenario Outline",
694
+ "name": "",
695
+ "line": 12,
696
+ "description": "",
697
+ "id": "an-embed-data-directly-feature;;;3",
698
+ "type": "scenario",
699
+ "steps": [
700
+ {
701
+ "keyword": "Given ",
702
+ "name": "I embed data directly",
703
+ "line": 12,
704
+ "embeddings": [
705
+ {
706
+ "mime_type": "mime-type",
707
+ "data": "YWJj"
708
+ }
709
+ ],
710
+ "match": {
711
+ "location": "features/step_definitions/json_steps.rb:10"
712
+ },
713
+ "result": {
714
+ "status": "passed",
715
+ "duration": 1
716
+ }
717
+ }
718
+ ]
655
719
  }
656
720
  ]
657
721
  }
@@ -274,3 +274,43 @@ You *must* specify --out DIR for the junit formatter
274
274
  </testsuite>
275
275
 
276
276
  """
277
+
278
+ Scenario: one feature, one scenario outline, two examples: one passing, one failing with --expand option
279
+ When I run `cucumber --expand --format junit --out tmp/ features/scenario_outline.feature`
280
+ Then it should fail with exactly:
281
+ """
282
+
283
+ """
284
+ And the junit output file "tmp/TEST-features-scenario_outline.xml" should contain:
285
+ """
286
+ <?xml version="1.0" encoding="UTF-8"?>
287
+ <testsuite failures="1" errors="0" skipped="0" tests="2" time="0.05" name="Scenario outlines">
288
+ <testcase classname="Scenario outlines" name="Using scenario outlines (outline example : | passes |)" time="0.05">
289
+ <system-out/>
290
+ <system-err/>
291
+ </testcase>
292
+ <testcase classname="Scenario outlines" name="Using scenario outlines (outline example : | fails |)" time="0.05">
293
+ <failure message="failed Using scenario outlines (outline example : | fails |)" type="failed">
294
+ <![CDATA[Scenario Outline: Using scenario outlines
295
+
296
+ Example row: | fails |
297
+
298
+ Message:
299
+ ]]>
300
+ <![CDATA[ (RuntimeError)
301
+ ./features/step_definitions/steps.rb:4:in `/^this step fails$/'
302
+ features/scenario_outline.feature:9:in `Given this step fails'
303
+ features/scenario_outline.feature:4:in `Given this step <type>']]>
304
+ </failure>
305
+ <system-out/>
306
+ <system-err/>
307
+ </testcase>
308
+ <system-out>
309
+ <![CDATA[]]>
310
+ </system-out>
311
+ <system-err>
312
+ <![CDATA[]]>
313
+ </system-err>
314
+ </testsuite>
315
+
316
+ """
@@ -1,6 +1,6 @@
1
1
  @wire
2
- Feature: Wire Protocol with ERB
3
- In order to be allow Cucumber to touch my app in intimate places
2
+ Feature: ERB configuration
3
+
4
4
  As a developer on server with multiple users
5
5
  I want to be able to configure which port my wire server runs on
6
6
  So that I can avoid port conflicts
@@ -0,0 +1,30 @@
1
+ @wire
2
+ Feature: Handle unexpected response
3
+
4
+ When the server sends us back a message we don't understand, this is how Cucumber will behave.
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
+ Scenario: Unexpected response
22
+ Given there is a wire server running on port 54321 which understands the following protocol:
23
+ | request | response |
24
+ | ["begin_scenario"] | ["yikes"] |
25
+ | ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[]}]] |
26
+ When I run `cucumber -f pretty`
27
+ Then the output should contain:
28
+ """
29
+ undefined method `handle_yikes'
30
+ """
@@ -0,0 +1,216 @@
1
+ @wire
2
+ Feature: Invoke message
3
+
4
+ Assuming a StepMatch was returned for a given step name, when it's time to
5
+ invoke that step definition, Cucumber will send an invoke message.
6
+
7
+ The invoke message contains the ID of the step definition, as returned by
8
+ the wire server in response to the the step_matches call, along with the
9
+ arguments that were parsed from the step name during the same step_matches
10
+ call.
11
+
12
+ The wire server will normally reply one of the following:
13
+
14
+ * `success`
15
+ * `fail`
16
+ * `pending` - optionally takes a message argument
17
+
18
+ This isn't quite the whole story: see also table_diffing.feature
19
+
20
+ Background:
21
+ Given a file named "features/wired.feature" with:
22
+ """
23
+ Feature: High strung
24
+ Scenario: Wired
25
+ Given we're all wired
26
+
27
+ """
28
+ And a file named "features/step_definitions/some_remote_place.wire" with:
29
+ """
30
+ host: localhost
31
+ port: 54321
32
+
33
+ """
34
+
35
+
36
+ @spawn
37
+ Scenario: Invoke a step definition which is pending
38
+ Given there is a wire server running on port 54321 which understands the following protocol:
39
+ | request | response |
40
+ | ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[]}]] |
41
+ | ["begin_scenario"] | ["success"] |
42
+ | ["invoke",{"id":"1","args":[]}] | ["pending", "I'll do it later"] |
43
+ | ["end_scenario"] | ["success"] |
44
+ When I run `cucumber -f pretty -q`
45
+ And it should pass with:
46
+ """
47
+ Feature: High strung
48
+
49
+ Scenario: Wired
50
+ Given we're all wired
51
+ I'll do it later (Cucumber::Pending)
52
+ features/wired.feature:3:in `Given we're all wired'
53
+
54
+ 1 scenario (1 pending)
55
+ 1 step (1 pending)
56
+
57
+ """
58
+
59
+ Scenario: Invoke a step definition which passes
60
+ Given there is a wire server running on port 54321 which understands the following protocol:
61
+ | request | response |
62
+ | ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[]}]] |
63
+ | ["begin_scenario"] | ["success"] |
64
+ | ["invoke",{"id":"1","args":[]}] | ["success"] |
65
+ | ["end_scenario"] | ["success"] |
66
+ When I run `cucumber -f progress`
67
+ And it should pass with:
68
+ """
69
+ .
70
+
71
+ 1 scenario (1 passed)
72
+ 1 step (1 passed)
73
+
74
+ """
75
+
76
+ @spawn
77
+ Scenario: Invoke a step definition which fails
78
+
79
+ If an invoked step definition fails, it can return details of the exception
80
+ in the reply to invoke. This causes a Cucumber::WireSupport::WireException to be
81
+ raised.
82
+
83
+ Valid arguments are:
84
+
85
+ - `message` (mandatory)
86
+ - `exception`
87
+ - `backtrace`
88
+
89
+ See the specs for Cucumber::WireSupport::WireException for more details
90
+
91
+ Given there is a wire server running on port 54321 which understands the following protocol:
92
+ | request | response |
93
+ | ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[]}]] |
94
+ | ["begin_scenario"] | ["success"] |
95
+ | ["invoke",{"id":"1","args":[]}] | ["fail",{"message":"The wires are down", "exception":"Some.Foreign.ExceptionType"}] |
96
+ | ["end_scenario"] | ["success"] |
97
+ When I run `cucumber -f progress`
98
+ Then the stderr should not contain anything
99
+ And it should fail with:
100
+ """
101
+ F
102
+
103
+ (::) failed steps (::)
104
+
105
+ The wires are down (Some.Foreign.ExceptionType from localhost:54321)
106
+ features/wired.feature:3:in `Given we're all wired'
107
+
108
+ Failing Scenarios:
109
+ cucumber features/wired.feature:2 # Scenario: Wired
110
+
111
+ 1 scenario (1 failed)
112
+ 1 step (1 failed)
113
+
114
+ """
115
+
116
+ Scenario: Invoke a step definition which takes string arguments (and passes)
117
+
118
+ If the step definition at the end of the wire captures arguments, these are
119
+ communicated back to Cucumber in the `step_matches` message.
120
+
121
+ Cucumber expects these StepArguments to be returned in the StepMatch. The keys
122
+ have the following meanings:
123
+
124
+ - `val` - the value of the string captured for that argument from the step
125
+ name passed in step_matches
126
+ - `pos` - the position within the step name that the argument was matched
127
+ (used for formatter highlighting)
128
+
129
+ The argument values are then sent back by Cucumber in the `invoke` message.
130
+
131
+ Given there is a wire server running on port 54321 which understands the following protocol:
132
+ | request | response |
133
+ | ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[{"val":"wired", "pos":10}]}]] |
134
+ | ["begin_scenario"] | ["success"] |
135
+ | ["invoke",{"id":"1","args":["wired"]}] | ["success"] |
136
+ | ["end_scenario"] | ["success"] |
137
+ When I run `cucumber -f progress`
138
+ Then the stderr should not contain anything
139
+ And it should pass with:
140
+ """
141
+ .
142
+
143
+ 1 scenario (1 passed)
144
+ 1 step (1 passed)
145
+
146
+ """
147
+
148
+ Scenario: Invoke a step definition which takes regular and table arguments (and passes)
149
+
150
+ If the step has a multiline table argument, it will be passed with the
151
+ invoke message as an array of array of strings.
152
+
153
+ In this scenario our step definition takes two arguments - one
154
+ captures the "we're" and the other takes the table.
155
+
156
+ Given a file named "features/wired_on_tables.feature" with:
157
+ """
158
+ Feature: High strung
159
+ Scenario: Wired and more
160
+ Given we're all:
161
+ | wired |
162
+ | high |
163
+ | happy |
164
+ """
165
+ And there is a wire server running on port 54321 which understands the following protocol:
166
+ | request | response |
167
+ | ["step_matches",{"name_to_match":"we're all:"}] | ["success",[{"id":"1", "args":[{"val":"we're", "pos":0}]}]] |
168
+ | ["begin_scenario"] | ["success"] |
169
+ | ["invoke",{"id":"1","args":["we're",[["wired"],["high"],["happy"]]]}] | ["success"] |
170
+ | ["end_scenario"] | ["success"] |
171
+ When I run `cucumber -f progress features/wired_on_tables.feature`
172
+ Then the stderr should not contain anything
173
+ And it should pass with:
174
+ """
175
+ .
176
+
177
+ 1 scenario (1 passed)
178
+ 1 step (1 passed)
179
+
180
+ """
181
+
182
+ Scenario: Invoke a scenario outline step
183
+ Given a file named "features/wired_in_an_outline.feature" with:
184
+ """
185
+ Feature:
186
+ Scenario Outline:
187
+ Given we're all <arg>
188
+
189
+ Examples:
190
+ | arg |
191
+ | wired |
192
+ """
193
+ And there is a wire server running on port 54321 which understands the following protocol:
194
+ | request | response |
195
+ | ["step_matches",{"name_to_match":"we're all wired"}] | ["success",[{"id":"1", "args":[]}]] |
196
+ | ["begin_scenario"] | ["success"] |
197
+ | ["invoke",{"id":"1","args":[]}] | ["success"] |
198
+ | ["end_scenario"] | ["success"] |
199
+ When I run `cucumber -f progress features/wired_in_an_outline.feature`
200
+ Then the stderr should not contain anything
201
+ And it should pass with:
202
+ """
203
+ .
204
+
205
+ 1 scenario (1 passed)
206
+ 1 step (1 passed)
207
+
208
+ """
209
+ And the wire server should have received the following messages:
210
+ | step_matches |
211
+ | begin_scenario |
212
+ | invoke |
213
+ | end_scenario |
214
+
215
+
216
+