cucumber 0.7.3 → 0.8.0

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.
Files changed (43) hide show
  1. data/History.txt +20 -1
  2. data/Rakefile +4 -4
  3. data/VERSION.yml +2 -2
  4. data/cucumber.gemspec +35 -23
  5. data/examples/json/features/background.feature +7 -0
  6. data/examples/json/features/one_passing_one_failing.feature +11 -0
  7. data/examples/json/features/pystring.feature +8 -0
  8. data/examples/json/features/step_definitions/steps.rb +27 -0
  9. data/examples/json/features/tables.feature +13 -0
  10. data/examples/json/tmp/out.json +1 -0
  11. data/examples/self_test/features/step_definitions/sample_steps.rb +1 -0
  12. data/examples/tickets/features/around_timeout.feature +6 -0
  13. data/examples/tickets/features/step_definitons/around_timeout_steps.rb +9 -0
  14. data/examples/{javascript → v8}/Rakefile +3 -1
  15. data/examples/{javascript → v8}/features/fibonacci.feature +4 -7
  16. data/examples/{javascript → v8}/features/step_definitions/fib_steps.js +7 -3
  17. data/examples/{javascript → v8}/features/support/env.js +3 -0
  18. data/examples/{javascript/features → v8}/lib/fibonacci.js +0 -0
  19. data/features/announce.feature +1 -1
  20. data/features/cucumber_cli_diff_disabled.feature +1 -24
  21. data/features/custom_formatter.feature +9 -3
  22. data/features/json_formatter.feature +281 -0
  23. data/features/step_definitions/cucumber_steps.rb +6 -1
  24. data/gem_tasks/rspec.rake +1 -1
  25. data/lib/cucumber/ast/feature.rb +1 -1
  26. data/lib/cucumber/cli/configuration.rb +8 -12
  27. data/lib/cucumber/cli/main.rb +0 -8
  28. data/lib/cucumber/cli/options.rb +22 -21
  29. data/lib/cucumber/formatter/json.rb +154 -0
  30. data/lib/cucumber/formatter/json_pretty.rb +14 -0
  31. data/lib/cucumber/js_support/js_dsl.js +14 -26
  32. data/lib/cucumber/js_support/js_language.rb +31 -16
  33. data/lib/cucumber/rb_support/rb_language.rb +22 -3
  34. data/spec/cucumber/ast/scenario_spec.rb +1 -1
  35. data/spec/cucumber/cli/configuration_spec.rb +8 -16
  36. data/spec/cucumber/cli/main_spec.rb +5 -5
  37. data/spec/cucumber/formatter/html_spec.rb +1 -1
  38. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +4 -4
  39. data/spec/cucumber/step_mother_spec.rb +1 -1
  40. data/spec/cucumber/world/pending_spec.rb +1 -1
  41. data/spec/spec_helper.rb +1 -1
  42. metadata +65 -21
  43. data/lib/cucumber/rspec/diffing.rb +0 -17
@@ -14,7 +14,8 @@ Feature: Custom Formatter
14
14
  Given a standard Cucumber project directory structure
15
15
  And a file named "features/f.feature" with:
16
16
  """
17
- Feature: i'll use my own
17
+ Feature: I'll use my own
18
+ because I'm worth it
18
19
  Scenario: just print me
19
20
  Given this step works
20
21
  """
@@ -32,8 +33,12 @@ Feature: Custom Formatter
32
33
  @io = io
33
34
  end
34
35
 
36
+ def before_feature(feature)
37
+ @io.puts feature.short_name.upcase
38
+ end
39
+
35
40
  def scenario_name(keyword, name, file_colon_line, source_indent)
36
- @io.puts "$ #{name.upcase}"
41
+ @io.puts " #{name.upcase}"
37
42
  end
38
43
  end
39
44
  end
@@ -42,7 +47,8 @@ Feature: Custom Formatter
42
47
  Then STDERR should be empty
43
48
  Then it should pass with
44
49
  """
45
- $ JUST PRINT ME
50
+ I'LL USE MY OWN
51
+ JUST PRINT ME
46
52
 
47
53
  """
48
54
 
@@ -0,0 +1,281 @@
1
+ Feature: JSON output formatter
2
+ In order to get results as data
3
+ As a developer
4
+ Cucumber should be able to output JSON
5
+
6
+ Background:
7
+ Given I am in json
8
+
9
+ Scenario: one feature, one passing scenario, one failing scenario
10
+ And the tmp directory is empty
11
+ When I run cucumber --format json --out tmp/out.json features/one_passing_one_failing.feature
12
+ Then STDERR should be empty
13
+ And it should fail with
14
+ """
15
+ """
16
+ And "examples/json/tmp/out.json" should match "^\{\"features\":\["
17
+
18
+ Scenario: one feature, one passing scenario, one failing scenario
19
+ When I run cucumber --format json_pretty features/one_passing_one_failing.feature
20
+ Then STDERR should be empty
21
+ And it should fail with JSON
22
+ """
23
+ {
24
+ "features": [
25
+ {
26
+ "file": "features/one_passing_one_failing.feature",
27
+ "name": "One passing scenario, one failing scenario",
28
+ "tags": [
29
+ "@a"
30
+ ],
31
+ "elements": [
32
+ {
33
+ "tags": [
34
+ "@b"
35
+ ],
36
+ "keyword": "Scenario",
37
+ "name": "Passing",
38
+ "file_colon_line": "features/one_passing_one_failing.feature:5",
39
+ "steps": [
40
+ {
41
+ "status": "passed",
42
+ "name": "Given a passing step",
43
+ "file_colon_line": "features/step_definitions/steps.rb:1"
44
+ }
45
+ ]
46
+ },
47
+ {
48
+ "tags": [
49
+ "@c"
50
+ ],
51
+ "keyword": "Scenario",
52
+ "name": "Failing",
53
+ "file_colon_line": "features/one_passing_one_failing.feature:9",
54
+ "steps": [
55
+ {
56
+ "exception": {
57
+ "class": "RuntimeError",
58
+ "message": "",
59
+ "backtrace": [
60
+ "./features/step_definitions/steps.rb:6:in `/a failing step/'",
61
+ "features/one_passing_one_failing.feature:10:in `Given a failing step'"
62
+ ]
63
+ },
64
+ "status": "failed",
65
+ "name": "Given a failing step",
66
+ "file_colon_line": "features/step_definitions/steps.rb:5"
67
+ }
68
+ ]
69
+ }
70
+ ]
71
+ }
72
+ ]
73
+ }
74
+ """
75
+
76
+ Scenario: Tables
77
+ When I run cucumber --format json_pretty features/tables.feature
78
+ Then STDERR should be empty
79
+ And it should fail with JSON
80
+ """
81
+ {
82
+ "features": [
83
+ {
84
+ "file": "features/tables.feature",
85
+ "name": "A scenario outline",
86
+ "tags": [
87
+
88
+ ],
89
+ "elements": [
90
+ {
91
+ "tags": [
92
+
93
+ ],
94
+ "keyword": "Scenario Outline",
95
+ "name": "",
96
+ "file_colon_line": "features/tables.feature:3",
97
+ "steps": [
98
+ {
99
+ "status": "skipped",
100
+ "name": "Given I add <a> and <b>",
101
+ "file_colon_line": "features/step_definitions/steps.rb:13"
102
+ },
103
+ {
104
+ "status": "skipped",
105
+ "name": "When I pass a table argument",
106
+ "file_colon_line": "features/step_definitions/steps.rb:25",
107
+ "table": [
108
+ {"cells":
109
+ [{"text":"foo", "status": null},
110
+ {"text":"bar", "status": null}]},
111
+ {"cells":
112
+ [{"text": "bar", "status": null},
113
+ {"text": "baz", "status": null}]}
114
+ ]
115
+ },
116
+ {
117
+ "status": "skipped",
118
+ "name": "Then I the result should be <c>",
119
+ "file_colon_line": "features/step_definitions/steps.rb:17"
120
+ }
121
+ ],
122
+ "examples": {
123
+ "name": "Examples ",
124
+ "table": [
125
+ {
126
+ "cells": [
127
+ {
128
+ "text": "a",
129
+ "status": "skipped_param"
130
+ },
131
+ {
132
+ "text": "b",
133
+ "status": "skipped_param"
134
+ },
135
+ {
136
+ "text": "c",
137
+ "status": "skipped_param"
138
+ }
139
+ ]
140
+ },
141
+ {
142
+ "cells": [
143
+ {
144
+ "text": "1",
145
+ "status": "passed"
146
+ },
147
+ {
148
+ "text": "2",
149
+ "status": "passed"
150
+ },
151
+ {
152
+ "text": "3",
153
+ "status": "passed"
154
+ }
155
+ ]
156
+ },
157
+ {
158
+ "cells": [
159
+ {
160
+ "text": "2",
161
+ "status": "passed"
162
+ },
163
+ {
164
+ "text": "3",
165
+ "status": "passed"
166
+ },
167
+ {
168
+ "text": "4",
169
+ "status": "failed"
170
+ }
171
+ ],
172
+ "exception": {
173
+ "class": "RSpec::Expectations::ExpectationNotMetError",
174
+ "message": "expected: 4,\n got: 5 (using ==)\nDiff:\n@@ -1,2 +1,2 @@\n-4\n+5\n",
175
+ "backtrace": [
176
+ "./features/step_definitions/steps.rb:18:in `/^I the result should be (\\d+)$/'",
177
+ "features/tables.feature:8:in `Then I the result should be <c>'"
178
+ ]
179
+ }
180
+ }
181
+ ]
182
+ }
183
+ }
184
+ ]
185
+ }
186
+ ]
187
+ }
188
+ """
189
+
190
+ Scenario: pystring
191
+ When I run cucumber --format json_pretty features/pystring.feature
192
+ Then STDERR should be empty
193
+ And it should pass with JSON
194
+ """
195
+ {
196
+ "features": [
197
+ {
198
+ "file": "features/pystring.feature",
199
+ "name": "A py string feature",
200
+ "tags": [
201
+
202
+ ],
203
+ "elements": [
204
+ {
205
+ "tags": [
206
+
207
+ ],
208
+ "keyword": "Scenario",
209
+ "name": "",
210
+ "file_colon_line": "features/pystring.feature:3",
211
+ "steps": [
212
+ {
213
+ "status": "passed",
214
+ "name": "Then I should see",
215
+ "file_colon_line": "features/step_definitions/steps.rb:21",
216
+ "py_string": "a string"
217
+ }
218
+ ]
219
+ }
220
+ ]
221
+ }
222
+ ]
223
+ }
224
+ """
225
+
226
+ Scenario: background
227
+ When I run cucumber --format json_pretty features/background.feature
228
+ Then STDERR should be empty
229
+ And it should fail with JSON
230
+ """
231
+ {
232
+ "features": [
233
+ {
234
+ "file": "features/background.feature",
235
+ "name": "Feature with background",
236
+ "tags": [
237
+
238
+ ],
239
+ "background": {
240
+ "steps": [
241
+ {
242
+ "status": "passed",
243
+ "name": "Given a passing step",
244
+ "file_colon_line": "features/step_definitions/steps.rb:1"
245
+ }
246
+ ]
247
+ },
248
+ "elements": [
249
+ {
250
+ "tags": [
251
+
252
+ ],
253
+ "keyword": "Scenario",
254
+ "name": "",
255
+ "file_colon_line": "features/background.feature:6",
256
+ "steps": [
257
+ {
258
+ "status": "passed",
259
+ "name": "Given a passing step",
260
+ "file_colon_line": "features/step_definitions/steps.rb:1"
261
+ },
262
+ {
263
+ "exception": {
264
+ "class": "RuntimeError",
265
+ "message": "",
266
+ "backtrace": [
267
+ "./features/step_definitions/steps.rb:6:in `/a failing step/'",
268
+ "features/background.feature:7:in `Given a failing step'"
269
+ ]
270
+ },
271
+ "status": "failed",
272
+ "name": "Given a failing step",
273
+ "file_colon_line": "features/step_definitions/steps.rb:5"
274
+ }
275
+ ]
276
+ }
277
+ ]
278
+ }
279
+ ]
280
+ }
281
+ """
@@ -84,6 +84,11 @@ Then /^the output should be$/ do |text|
84
84
  last_stdout.should == text
85
85
  end
86
86
 
87
+ Then /^it should (fail|pass) with JSON$/ do |success, text|
88
+ JSON.parse(last_stdout).should == JSON.parse(text)
89
+ Then("it should #{success}")
90
+ end
91
+
87
92
  Then /^"([^"]*)" should contain$/ do |file, text|
88
93
  strip_duration(IO.read(file)).should == text
89
94
  end
@@ -95,7 +100,7 @@ Then /^"([^"]*)" with junit duration "([^"]*)" should contain$/ do |actual_file,
95
100
  actual.should == text
96
101
  end
97
102
 
98
- Then /^"([^"]*)" should match "([^"]*)"$/ do |file, text|
103
+ Then /^"([^"]*)" should match "(.+?)"$/ do |file, text|
99
104
  File.open(file, Cucumber.file_mode('r')).read.should =~ Regexp.new(text)
100
105
  end
101
106
 
@@ -2,7 +2,7 @@ begin
2
2
  require 'rspec/core/rake_task'
3
3
 
4
4
  desc "Run RSpec"
5
- Rspec::Core::RakeTask.new do |t|
5
+ RSpec::Core::RakeTask.new do |t|
6
6
  t.rcov = ENV['RCOV']
7
7
  t.rcov_opts = %w{--exclude osx\/objc,gems\/,spec\/}
8
8
  t.verbose = true
@@ -80,7 +80,7 @@ module Cucumber
80
80
 
81
81
  def short_name
82
82
  first_line = name.split(/\n/)[0]
83
- if first_line =~ /#{language.keywords('feature', true)}:(.*)/
83
+ if first_line =~ /#{language.keywords('feature')}:(.*)/
84
84
  $1.strip
85
85
  else
86
86
  first_line
@@ -11,7 +11,7 @@ module Cucumber
11
11
 
12
12
  class Configuration
13
13
  include Constantize
14
-
14
+
15
15
  attr_reader :options, :out_stream
16
16
 
17
17
  def initialize(out_stream = STDOUT, error_stream = STDERR)
@@ -48,10 +48,6 @@ module Cucumber
48
48
  @options[:guess]
49
49
  end
50
50
 
51
- def diff_enabled?
52
- @options[:diff_enabled]
53
- end
54
-
55
51
  def drb?
56
52
  @options[:drb]
57
53
  end
@@ -85,11 +81,11 @@ module Cucumber
85
81
  files.reject! {|f| f =~ /^http/}
86
82
  files.sort
87
83
  end
88
-
84
+
89
85
  def step_defs_to_load
90
86
  all_files_to_load.reject {|f| f =~ %r{/support/} }
91
87
  end
92
-
88
+
93
89
  def support_to_load
94
90
  support_files = all_files_to_load.select {|f| f =~ %r{/support/} }
95
91
  env_files = support_files.select {|f| f =~ %r{/support/env\..*} }
@@ -106,14 +102,14 @@ module Cucumber
106
102
  elsif path[0..0] == '@' and # @listfile.txt
107
103
  File.file?(path[1..-1]) # listfile.txt is a file
108
104
  IO.read(path[1..-1]).split
109
- else
105
+ else
110
106
  path
111
107
  end
112
108
  end.flatten.uniq
113
109
  remove_excluded_files_from(potential_feature_files)
114
- potential_feature_files.sort
110
+ potential_feature_files
115
111
  end
116
-
112
+
117
113
  def feature_dirs
118
114
  paths.map { |f| File.directory?(f) ? f : File.dirname(f) }.uniq
119
115
  end
@@ -127,7 +123,7 @@ module Cucumber
127
123
  end
128
124
 
129
125
  private
130
-
126
+
131
127
  def formatters(step_mother)
132
128
  # TODO: We should remove the autoformat functionality. That
133
129
  # can be done with the gherkin CLI.
@@ -181,7 +177,7 @@ module Cucumber
181
177
  def require_dirs
182
178
  feature_dirs + Dir['vendor/{gems,plugins}/*/cucumber']
183
179
  end
184
-
180
+
185
181
  end
186
182
 
187
183
  end
@@ -55,8 +55,6 @@ module Cucumber
55
55
  features = step_mother.load_plain_text_features(configuration.feature_files)
56
56
  step_mother.load_code_files(configuration.step_defs_to_load)
57
57
 
58
- enable_diffing
59
-
60
58
  tag_excess = tag_excess(features)
61
59
  configuration.options[:tag_excess] = tag_excess # Hack to make it available in console.rb - later: stick on Run instance.
62
60
 
@@ -99,12 +97,6 @@ module Cucumber
99
97
 
100
98
  private
101
99
 
102
- def enable_diffing
103
- if configuration.diff_enabled?
104
- require 'cucumber/rspec/diffing'
105
- end
106
- end
107
-
108
100
  def trap_interrupt
109
101
  trap('INT') do
110
102
  exit!(1) if Cucumber.wants_to_quit
@@ -6,25 +6,28 @@ module Cucumber
6
6
  module Cli
7
7
 
8
8
  class Options
9
+ INDENT = ' ' * 53
9
10
  BUILTIN_FORMATS = {
10
- 'html' => ['Cucumber::Formatter::Html', 'Generates a nice looking HTML report.'],
11
- 'pretty' => ['Cucumber::Formatter::Pretty', 'Prints the feature as is - in colours.'],
12
- 'pdf' => ['Cucumber::Formatter::Pdf', "Generates a PDF report. You need to have the\n" +
13
- "#{' ' * 51}prawn gem installed. Will pick up logo from\n" +
14
- "#{' ' * 51}features/support/logo.png or\n" +
15
- "#{' ' * 51}features/support/logo.jpg if present."],
16
- 'progress' => ['Cucumber::Formatter::Progress', 'Prints one character per scenario.'],
17
- 'rerun' => ['Cucumber::Formatter::Rerun', 'Prints failing files with line numbers.'],
18
- 'usage' => ['Cucumber::Formatter::Usage', "Prints where step definitions are used.\n" +
19
- "#{' ' * 51}The slowest step definitions (with duration) are\n" +
20
- "#{' ' * 51}listed first. If --dry-run is used the duration\n" +
21
- "#{' ' * 51}is not shown, and step definitions are sorted by\n" +
22
- "#{' ' * 51}filename instead."],
23
- 'stepdefs' => ['Cucumber::Formatter::Stepdefs', "Prints All step definitions with their locations. Same as\n" +
24
- "#{' ' * 51}the usage formatter, except that steps are not printed."],
25
- 'junit' => ['Cucumber::Formatter::Junit', 'Generates a report similar to Ant+JUnit.'],
26
- 'tag_cloud' => ['Cucumber::Formatter::TagCloud', 'Prints a tag cloud of tag usage.'],
27
- 'debug' => ['Cucumber::Formatter::Debug', 'For developing formatters - prints the calls made to the listeners.']
11
+ 'html' => ['Cucumber::Formatter::Html', 'Generates a nice looking HTML report.'],
12
+ 'pretty' => ['Cucumber::Formatter::Pretty', 'Prints the feature as is - in colours.'],
13
+ 'pdf' => ['Cucumber::Formatter::Pdf', "Generates a PDF report. You need to have the\n" +
14
+ "#{INDENT}prawn gem installed. Will pick up logo from\n" +
15
+ "#{INDENT}features/support/logo.png or\n" +
16
+ "#{INDENT}features/support/logo.jpg if present."],
17
+ 'progress' => ['Cucumber::Formatter::Progress', 'Prints one character per scenario.'],
18
+ 'rerun' => ['Cucumber::Formatter::Rerun', 'Prints failing files with line numbers.'],
19
+ 'usage' => ['Cucumber::Formatter::Usage', "Prints where step definitions are used.\n" +
20
+ "#{INDENT}The slowest step definitions (with duration) are\n" +
21
+ "#{INDENT}listed first. If --dry-run is used the duration\n" +
22
+ "#{INDENT}is not shown, and step definitions are sorted by\n" +
23
+ "#{INDENT}filename instead."],
24
+ 'stepdefs' => ['Cucumber::Formatter::Stepdefs', "Prints All step definitions with their locations. Same as\n" +
25
+ "#{INDENT}the usage formatter, except that steps are not printed."],
26
+ 'junit' => ['Cucumber::Formatter::Junit', 'Generates a report similar to Ant+JUnit.'],
27
+ 'json' => ['Cucumber::Formatter::Json', 'Prints the feature as JSON'],
28
+ 'json_pretty' => ['Cucumber::Formatter::JsonPretty', 'Prints the feature as pretty JSON'],
29
+ 'tag_cloud' => ['Cucumber::Formatter::TagCloud', 'Prints a tag cloud of tag usage.'],
30
+ 'debug' => ['Cucumber::Formatter::Debug', 'For developing formatters - prints the calls made to the listeners.']
28
31
  }
29
32
  max = BUILTIN_FORMATS.keys.map{|s| s.length}.max
30
33
  FORMAT_HELP = (BUILTIN_FORMATS.keys.sort.map do |key|
@@ -118,6 +121,7 @@ module Cucumber
118
121
  "This option can be specified multiple times.") do |v|
119
122
  @options[:require] << v
120
123
  if(Cucumber::JRUBY && File.directory?(v))
124
+ require 'java'
121
125
  $CLASSPATH << v
122
126
  end
123
127
  end
@@ -243,9 +247,6 @@ module Cucumber
243
247
  opts.on("-x", "--expand", "Expand Scenario Outline Tables in output.") do
244
248
  @options[:expand] = true
245
249
  end
246
- opts.on("--no-diff", "Disable diff output on failing expectations.") do
247
- @options[:diff_enabled] = false
248
- end
249
250
  opts.on(DRB_FLAG, "Run features against a DRb server. (i.e. with the spork gem)") do
250
251
  @options[:drb] = true
251
252
  end