kosmas58-cucumber 0.2.0.1 → 0.2.2.1

Sign up to get free protection for your applications and to get access to all the features.
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