kosmas58-cucumber 0.2.0.1 → 0.2.2.1

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 (52) hide show
  1. data/History.txt +32 -1
  2. data/Manifest.txt +4 -11
  3. data/examples/dos_line_endings/features/dos_line_endings.feature +9 -9
  4. data/examples/pure_java/README.textile +5 -0
  5. data/examples/self_test/features/tons_of_cukes.feature +52 -0
  6. data/examples/sinatra/features/support/env.rb +6 -2
  7. data/examples/tickets/features/248.feature +11 -0
  8. data/examples/tickets/features/step_definitons/248_steps.rb +15 -0
  9. data/features/cucumber_cli.feature +1 -1
  10. data/features/custom_formatter.feature +2 -2
  11. data/features/usage.feature +108 -0
  12. data/gem_tasks/features.rake +18 -6
  13. data/lib/autotest/cucumber_mixin.rb +1 -1
  14. data/lib/cucumber/ast/feature.rb +1 -1
  15. data/lib/cucumber/ast/features.rb +6 -0
  16. data/lib/cucumber/ast/step.rb +4 -0
  17. data/lib/cucumber/ast/step_invocation.rb +10 -2
  18. data/lib/cucumber/ast/table.rb +4 -0
  19. data/lib/cucumber/cli/configuration.rb +11 -14
  20. data/lib/cucumber/cli/main.rb +14 -21
  21. data/lib/cucumber/core_ext/exception.rb +1 -1
  22. data/lib/cucumber/formatter.rb +1 -1
  23. data/lib/cucumber/formatter/html.rb +47 -8
  24. data/lib/cucumber/formatter/pretty.rb +1 -2
  25. data/lib/cucumber/formatter/rerun.rb +8 -0
  26. data/lib/cucumber/formatter/usage.rb +69 -0
  27. data/lib/cucumber/languages.yml +7 -2
  28. data/lib/cucumber/rails/world.rb +22 -21
  29. data/lib/cucumber/step_definition.rb +65 -54
  30. data/lib/cucumber/step_match.rb +10 -2
  31. data/lib/cucumber/step_mother.rb +4 -10
  32. data/lib/cucumber/version.rb +1 -1
  33. data/rails_generators/cucumber/templates/env.rb +2 -0
  34. data/rails_generators/feature/templates/steps.erb +1 -1
  35. data/spec/cucumber/ast/feature_spec.rb +2 -1
  36. data/spec/cucumber/cli/configuration_spec.rb +18 -6
  37. data/spec/cucumber/cli/main_spec.rb +1 -14
  38. data/spec/cucumber/parser/feature_parser_spec.rb +15 -15
  39. data/spec/cucumber/step_definition_spec.rb +21 -9
  40. data/spec/cucumber/step_mother_spec.rb +17 -1
  41. metadata +8 -13
  42. data/examples/jbehave/README.textile +0 -20
  43. data/examples/jbehave/features/support/env.rb +0 -7
  44. data/examples/jbehave/features/trading.feature +0 -28
  45. data/examples/jbehave/pom.xml +0 -53
  46. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/converters/TraderConverter.java +0 -32
  47. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/model/Stock.java +0 -42
  48. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/model/Trader.java +0 -29
  49. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/persistence/TraderPersister.java +0 -22
  50. data/examples/jbehave/src/main/java/cukes/jbehave/examples/trader/scenarios/TraderSteps.java +0 -70
  51. data/gem_tasks/jar.rake +0 -67
  52. data/lib/cucumber/jbehave.rb +0 -97
@@ -264,6 +264,10 @@ module Cucumber
264
264
  @cells[0].line
265
265
  end
266
266
 
267
+ def dom_id
268
+ "row_#{line}"
269
+ end
270
+
267
271
  def status=(status)
268
272
  each do |cell|
269
273
  cell.status = status
@@ -1,7 +1,7 @@
1
1
  module Cucumber
2
2
  module Cli
3
3
  class YmlLoadError < StandardError; end
4
-
4
+
5
5
  class Configuration
6
6
  FORMATS = %w{pretty profile progress rerun}
7
7
  DEFAULT_FORMAT = 'pretty'
@@ -95,6 +95,7 @@ module Cucumber
95
95
  Term::ANSIColor.coloring = v
96
96
  end
97
97
  opts.on("-d", "--dry-run", "Invokes formatters without executing the steps.",
98
+ "This also omits the loading of your support/env.rb file if it exists.",
98
99
  "Implies --quiet.") do
99
100
  @options[:dry_run] = true
100
101
  @quiet = true
@@ -137,9 +138,6 @@ module Cucumber
137
138
  opts.on("--no-diff", "Disable diff output on failing expectations.") do
138
139
  @options[:diff_enabled] = false
139
140
  end
140
- opts.on("-S", "--step-definitions", "Print the regexp and line of all step definitions, then exit.") do
141
- @options[:print_step_definitions] = true
142
- end
143
141
  opts.on_tail("--version", "Show version.") do
144
142
  @out_stream.puts VERSION::STRING
145
143
  Kernel.exit
@@ -175,10 +173,6 @@ module Cucumber
175
173
  @options[:diff_enabled]
176
174
  end
177
175
 
178
- def print_step_definitions?
179
- @options[:print_step_definitions]
180
- end
181
-
182
176
  def load_language
183
177
  if Cucumber.language_incomplete?(@options[:lang])
184
178
  list_keywords_and_exit(@options[:lang])
@@ -224,11 +218,12 @@ module Cucumber
224
218
 
225
219
  def formatter_class(format)
226
220
  case format
221
+ when 'html' then Formatter::Html
227
222
  when 'pretty' then Formatter::Pretty
228
- when 'progress' then Formatter::Progress
229
223
  when 'profile' then Formatter::Profile
224
+ when 'progress' then Formatter::Progress
230
225
  when 'rerun' then Formatter::Rerun
231
- when 'html' then Formatter::Html
226
+ when 'usage' then Formatter::Usage
232
227
  else
233
228
  constantize(format)
234
229
  end
@@ -242,7 +237,9 @@ module Cucumber
242
237
  end.flatten.uniq
243
238
  sorted_files = files.sort { |a,b| (b =~ %r{/support/} || -1) <=> (a =~ %r{/support/} || -1) }.reject{|f| f =~ /^http/}
244
239
  env_files = sorted_files.select {|f| f =~ %r{/support/env.rb} }
245
- env_files + sorted_files.reject {|f| f =~ %r{/support/env.rb} }
240
+ files = env_files + sorted_files.reject {|f| f =~ %r{/support/env.rb} }
241
+ files.reject! {|f| f =~ %r{/support/env.rb} } if @options[:dry_run]
242
+ files
246
243
  end
247
244
 
248
245
  def feature_files
@@ -305,18 +302,18 @@ Defined profiles in cucumber.yml:
305
302
  def cucumber_yml
306
303
  return @cucumber_yml if @cucumber_yml
307
304
  unless File.exist?('cucumber.yml')
308
- raise(YmlLoadError,"cucumber.yml was not found. Please refer to cucumber's documentaion on defining profiles in cucumber.yml. You must define a 'default' profile to use the cucumber command without any arguments.\nType 'cucumber --help' for usage.\n")
305
+ raise(YmlLoadError,"cucumber.yml was not found. Please refer to cucumber's documentation on defining profiles in cucumber.yml. You must define a 'default' profile to use the cucumber command without any arguments.\nType 'cucumber --help' for usage.\n")
309
306
  end
310
307
 
311
308
  require 'yaml'
312
309
  begin
313
310
  @cucumber_yml = YAML::load(IO.read('cucumber.yml'))
314
311
  rescue Exception => e
315
- raise(YmlLoadError,"cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentaion on correct profile usage.\n")
312
+ raise(YmlLoadError,"cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentation on correct profile usage.\n")
316
313
  end
317
314
 
318
315
  if @cucumber_yml.nil? || !@cucumber_yml.is_a?(Hash)
319
- raise(YmlLoadError,"cucumber.yml was found, but was blank or malformed. Please refer to cucumber's documentaion on correct profile usage.\n")
316
+ raise(YmlLoadError,"cucumber.yml was found, but was blank or malformed. Please refer to cucumber's documentation on correct profile usage.\n")
320
317
  end
321
318
 
322
319
  return @cucumber_yml
@@ -32,13 +32,6 @@ module Cucumber
32
32
  step_mother.options = configuration.options
33
33
 
34
34
  require_files
35
-
36
- if(configuration.print_step_definitions?)
37
- step_mother.print_step_definitions(@out_stream)
38
- Kernel.exit(0)
39
- return # In specs, exit is stubbed
40
- end
41
-
42
35
  enable_diffing
43
36
 
44
37
  features = load_plain_text_features
@@ -53,7 +46,18 @@ module Cucumber
53
46
  Kernel.exit(failure ? 1 : 0)
54
47
  end
55
48
 
56
- private
49
+ def load_plain_text_features
50
+ features = Ast::Features.new
51
+ parser = Parser::FeatureParser.new
52
+
53
+ verbose_log("Features:")
54
+ configuration.feature_files.each do |f|
55
+ features.add_feature(parser.parse_file(f))
56
+ verbose_log(" * #{f}")
57
+ end
58
+ verbose_log("\n"*2)
59
+ features
60
+ end
57
61
 
58
62
  def configuration
59
63
  return @configuration if @configuration
@@ -62,6 +66,8 @@ module Cucumber
62
66
  @configuration.parse!(@args)
63
67
  @configuration
64
68
  end
69
+
70
+ private
65
71
 
66
72
  def require_files
67
73
  verbose_log("Ruby files required:")
@@ -77,19 +83,6 @@ module Cucumber
77
83
  verbose_log("\n")
78
84
  end
79
85
 
80
- def load_plain_text_features
81
- features = Ast::Features.new
82
- parser = Parser::FeatureParser.new
83
-
84
- verbose_log("Features:")
85
- configuration.feature_files.each do |f|
86
- features.add_feature(parser.parse_file(f))
87
- verbose_log(" * #{f}")
88
- end
89
- verbose_log("\n"*2)
90
- features
91
- end
92
-
93
86
  def verbose_log(string)
94
87
  @out_stream.puts(string) if configuration.verbose?
95
88
  end
@@ -20,7 +20,7 @@
20
20
  #
21
21
  class Exception
22
22
  CUCUMBER_FILTER_PATTERNS = [
23
- /vendor\/rails|lib\/cucumber|lib\/rspec|gems\//
23
+ /vendor\/rails|lib\/cucumber|bin\/cucumber:|lib\/rspec|gems\//
24
24
  ]
25
25
 
26
26
  INSTANCE_EXEC_OFFSET = (Cucumber::RUBY_1_9 || Cucumber::JRUBY) ? -3 : -4
@@ -1 +1 @@
1
- %w{color_io pretty progress profile rerun html}.each{|n| require "cucumber/formatter/#{n}"}
1
+ %w{color_io pretty progress profile rerun html usage}.each{|n| require "cucumber/formatter/#{n}"}
@@ -83,37 +83,73 @@ module Cucumber
83
83
  @builder.h4("#{keyword} #{name}")
84
84
  end
85
85
 
86
- def visit_steps(scenarios)
86
+ def visit_steps(steps)
87
87
  @builder.ol do
88
88
  super
89
89
  end
90
90
  end
91
91
 
92
+ def visit_step(step)
93
+ @step_id = step.dom_id
94
+ @builder.li(:id => @step_id) do
95
+ super
96
+ end
97
+ end
98
+
92
99
  def visit_step_name(keyword, step_match, status, source_indent, background)
93
- step_name = step_match.format_args(lambda{|param| "<span>#{param}</span>"})
94
- @builder.li("#{keyword} #{step_name}", :class => status)
100
+ @step_matches ||= []
101
+ @skip_step = @step_matches.index(step_match)
102
+ @step_matches << step_match
103
+
104
+ unless @skip_step
105
+ step_name = step_match.format_args(lambda{|param| "<span>#{param}</span>"})
106
+ @builder.div(:class => status) do |div|
107
+ div << "#{keyword} #{step_name}"
108
+ end
109
+ end
110
+ end
111
+
112
+ def visit_exception(exception, status)
113
+ @builder.pre(format_exception(exception), :class => status)
95
114
  end
96
115
 
97
116
  def visit_multiline_arg(multiline_arg)
117
+ return if @skip_step
98
118
  if Ast::Table === multiline_arg
99
119
  @builder.table do
100
120
  super
101
121
  end
102
122
  else
103
- @builder.p do
104
- super
105
- end
123
+ super
124
+ end
125
+ end
126
+
127
+ def visit_py_string(string, status)
128
+ @builder.pre(:class => status) do |pre|
129
+ pre << string
106
130
  end
107
131
  end
108
132
 
109
133
  def visit_table_row(table_row)
110
- @builder.tr do
134
+ @row_id = table_row.dom_id
135
+ @col_index = 0
136
+ @builder.tr(:id => @row_id) do
111
137
  super
112
138
  end
139
+ if table_row.exception
140
+ @builder.tr do
141
+ @builder.td(:colspan => @col_index.to_s, :class => 'failed') do
142
+ @builder.pre do |pre|
143
+ pre << format_exception(table_row.exception)
144
+ end
145
+ end
146
+ end
147
+ end
113
148
  end
114
149
 
115
150
  def visit_table_cell_value(value, width, status)
116
- @builder.td(value, :class => status)
151
+ @builder.td(value, :class => status, :id => "#{@row_id}_#{@col_index}")
152
+ @col_index += 1
117
153
  end
118
154
 
119
155
  def announce(announcement)
@@ -128,6 +164,9 @@ module Cucumber
128
164
  end
129
165
  end
130
166
 
167
+ def format_exception(exception)
168
+ (["#{exception.message} (#{exception.class})"] + exception.backtrace).join("\n")
169
+ end
131
170
  end
132
171
  end
133
172
  end
@@ -121,16 +121,15 @@ module Cucumber
121
121
 
122
122
  def visit_step_name(keyword, step_match, status, source_indent, background)
123
123
  @step_matches ||= []
124
-
125
124
  non_failed_background_step_outside_background = !@in_background && background && (status != :failed)
126
125
  @skip_step = @step_matches.index(step_match) || non_failed_background_step_outside_background
126
+ @step_matches << step_match
127
127
 
128
128
  unless(@skip_step)
129
129
  source_indent = nil unless @options[:source]
130
130
  formatted_step_name = format_step(keyword, step_match, status, source_indent)
131
131
  @io.puts(" " + formatted_step_name)
132
132
  end
133
- @step_matches << step_match
134
133
  end
135
134
 
136
135
  def visit_multiline_arg(multiline_arg)
@@ -1,5 +1,13 @@
1
1
  module Cucumber
2
2
  module Formatter
3
+ # This formatter keeps track of all failing features and print out their location.
4
+ # Example:
5
+ #
6
+ # features/foo.feature:34 features/bar.feature:11:76:81
7
+ #
8
+ # This formatter is used by AutoTest - it will use the output to decide what
9
+ # to run the next time, simply passing the output string on the command line.
10
+ #
3
11
  class Rerun < Ast::Visitor
4
12
  def initialize(step_mother, io, options)
5
13
  super(step_mother)
@@ -0,0 +1,69 @@
1
+ require 'cucumber/formatter/progress'
2
+
3
+ module Cucumber
4
+ module Formatter
5
+ class Usage < Ast::Visitor
6
+ include Console
7
+
8
+ def initialize(step_mother, io, options)
9
+ super(step_mother)
10
+ @io = io
11
+ @options = options
12
+ @step_definitions = Hash.new { |h,step_definition| h[step_definition] = [] }
13
+ @locations = []
14
+ end
15
+
16
+ def visit_features(features)
17
+ super
18
+ print_summary
19
+ end
20
+
21
+ def visit_step(step)
22
+ @step = step
23
+ super
24
+ end
25
+
26
+ def visit_step_name(keyword, step_match, status, source_indent, background)
27
+ if step_match.step_definition
28
+ location = @step.file_colon_line
29
+ return if @locations.index(location)
30
+ @locations << location
31
+
32
+ description = format_step(keyword, step_match, status, nil)
33
+ length = (keyword + step_match.format_args).jlength
34
+ @step_definitions[step_match.step_definition] << [step_match, description, length, location]
35
+ end
36
+ end
37
+
38
+ def print_summary
39
+ sorted_defs = @step_definitions.keys.sort_by{|step_definition| step_definition.backtrace_line}
40
+
41
+ sorted_defs.each do |step_definition|
42
+ step_matches_and_descriptions = @step_definitions[step_definition].sort_by do |step_match_and_description|
43
+ step_match = step_match_and_description[0]
44
+ step_match.step_definition.regexp.inspect
45
+ end
46
+
47
+ step_matches = step_matches_and_descriptions.map{|step_match_and_description| step_match_and_description[0]}
48
+
49
+ lengths = step_matches_and_descriptions.map do |step_match_and_description|
50
+ step_match_and_description[2]
51
+ end
52
+ lengths << step_definition.text_length
53
+ max_length = lengths.max
54
+
55
+ @io.print step_definition.regexp.inspect
56
+ @io.puts format_string(" # #{step_definition.file_colon_line}".indent(max_length - step_definition.text_length), :comment)
57
+ step_matches_and_descriptions.each do |step_match_and_description|
58
+ step_match = step_match_and_description[0]
59
+ description = step_match_and_description[1]
60
+ length = step_match_and_description[2]
61
+ file_colon_line = step_match_and_description[3]
62
+ @io.print " #{description}"
63
+ @io.puts format_string(" # #{file_colon_line}".indent(max_length - length), :comment)
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -211,8 +211,10 @@
211
211
  native: italiano
212
212
  encoding: UTF-8
213
213
  feature: Funzionalità
214
+ background: Contesto
214
215
  scenario: Scenario
215
- more_examples: Più esempi
216
+ scenario_outline: Schema dello scenario
217
+ examples: Esempi
216
218
  given: Dato
217
219
  when: Quando
218
220
  then: Allora
@@ -225,7 +227,7 @@
225
227
  feature: フィーチャ
226
228
  background: 背景
227
229
  scenario: シナリオ
228
- scenario_outline: シナリオテンプレート|テンプレ|シナリオテンプレ
230
+ scenario_outline: シナリオアウトライン|シナリオテンプレート|テンプレ|シナリオテンプレ
229
231
  examples: 例|サンプル
230
232
  given: 前提
231
233
  when: もし
@@ -249,7 +251,10 @@
249
251
  native: Nederlands
250
252
  encoding: UTF-8
251
253
  feature: Functionaliteit
254
+ background: Achtergrond
252
255
  scenario: Scenario
256
+ scenario_outline: Abstract Scenario
257
+ examples: Voorbeelden
253
258
  given: Gegeven
254
259
  when: Als
255
260
  then: Dan
@@ -9,22 +9,10 @@ else
9
9
  end
10
10
  require 'test/unit/testresult'
11
11
 
12
- # These allow exceptions to come through as opposed to being caught and having non-helpful responses returned.
13
- ActionController::Base.class_eval do
14
- def rescue_action(exception)
15
- raise exception
16
- end
17
- end
18
- ActionController::Dispatcher.class_eval do
19
- def self.failsafe_response(output, status, exception = nil)
20
- raise exception
21
- end
22
- end
23
-
24
12
  # So that Test::Unit doesn't launch at the end - makes it think it has already been run.
25
13
  Test::Unit.run = true if Test::Unit.respond_to?(:run=)
26
14
 
27
- $cucumber_toplevel = self
15
+ $__cucumber_toplevel = self
28
16
 
29
17
  module Cucumber #:nodoc:
30
18
  module Rails
@@ -44,20 +32,21 @@ module Cucumber #:nodoc:
44
32
  def self.use_transactional_fixtures
45
33
  World.use_transactional_fixtures = true
46
34
  if defined?(ActiveRecord::Base)
47
- $cucumber_toplevel.Before do
48
- if ActiveRecord::Base.connection.respond_to?(:increment_open_transactions)
49
- ActiveRecord::Base.connection.increment_open_transactions
35
+ $__cucumber_toplevel.Before do
36
+ @__cucumber_ar_connection = ActiveRecord::Base.connection
37
+ if @__cucumber_ar_connection.respond_to?(:increment_open_transactions)
38
+ @__cucumber_ar_connection.increment_open_transactions
50
39
  else
51
40
  ActiveRecord::Base.__send__(:increment_open_transactions)
52
41
  end
53
- ActiveRecord::Base.connection.begin_db_transaction
42
+ @__cucumber_ar_connection.begin_db_transaction
54
43
  ActionMailer::Base.deliveries = [] if defined?(ActionMailer::Base)
55
44
  end
56
45
 
57
- $cucumber_toplevel.After do
58
- ActiveRecord::Base.connection.rollback_db_transaction
59
- if ActiveRecord::Base.connection.respond_to?(:decrement_open_transactions)
60
- ActiveRecord::Base.connection.decrement_open_transactions
46
+ $__cucumber_toplevel.After do
47
+ @__cucumber_ar_connection.rollback_db_transaction
48
+ if @__cucumber_ar_connection.respond_to?(:decrement_open_transactions)
49
+ @__cucumber_ar_connection.decrement_open_transactions
61
50
  else
62
51
  ActiveRecord::Base.__send__(:decrement_open_transactions)
63
52
  end
@@ -65,6 +54,18 @@ module Cucumber #:nodoc:
65
54
  end
66
55
  end
67
56
 
57
+ def self.bypass_rescue
58
+ ActionController::Base.class_eval do
59
+ def rescue_action(exception)
60
+ raise exception
61
+ end
62
+ end
63
+ ActionController::Dispatcher.class_eval do
64
+ def self.failsafe_response(output, status, exception = nil)
65
+ raise exception
66
+ end
67
+ end
68
+ end
68
69
  end
69
70
  end
70
71