cucumber 0.3.9 → 0.3.10

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 (50) hide show
  1. data/History.txt +40 -0
  2. data/Manifest.txt +10 -0
  3. data/cucumber.yml +1 -1
  4. data/examples/i18n/pl/Rakefile +6 -0
  5. data/examples/i18n/pl/features/addition.feature +16 -0
  6. data/examples/i18n/pl/features/division.feature +9 -0
  7. data/examples/i18n/pl/features/step_definitons/calculator_steps.rb +24 -0
  8. data/examples/i18n/pl/features/support/env.rb +6 -0
  9. data/examples/i18n/pl/lib/calculator.rb +14 -0
  10. data/examples/self_test/features/sample.feature +2 -0
  11. data/features/cucumber_cli.feature +24 -6
  12. data/features/drb_server_integration.feature +92 -0
  13. data/features/html_formatter/a.html +926 -437
  14. data/features/junit_formatter.feature +11 -2
  15. data/features/step_definitions/cucumber_steps.rb +15 -2
  16. data/features/support/env.rb +35 -1
  17. data/features/usage.feature +2 -2
  18. data/lib/cucumber/ast/background.rb +1 -1
  19. data/lib/cucumber/ast/comment.rb +4 -0
  20. data/lib/cucumber/ast/feature.rb +2 -1
  21. data/lib/cucumber/ast/outline_table.rb +2 -2
  22. data/lib/cucumber/ast/scenario.rb +1 -1
  23. data/lib/cucumber/ast/scenario_outline.rb +11 -4
  24. data/lib/cucumber/ast/step_invocation.rb +17 -12
  25. data/lib/cucumber/ast/visitor.rb +4 -0
  26. data/lib/cucumber/cli/configuration.rb +32 -8
  27. data/lib/cucumber/cli/drb_client.rb +21 -0
  28. data/lib/cucumber/cli/main.rb +9 -0
  29. data/lib/cucumber/formatter/color_io.rb +2 -2
  30. data/lib/cucumber/formatter/console.rb +1 -3
  31. data/lib/cucumber/formatter/html.rb +63 -12
  32. data/lib/cucumber/formatter/junit.rb +2 -2
  33. data/lib/cucumber/formatter/pretty.rb +2 -1
  34. data/lib/cucumber/formatter/rerun.rb +1 -0
  35. data/lib/cucumber/formatter/tag_cloud.rb +1 -0
  36. data/lib/cucumber/rails/rspec.rb +5 -3
  37. data/lib/cucumber/rake/task.rb +1 -1
  38. data/lib/cucumber/step_match.rb +6 -2
  39. data/lib/cucumber/step_mother.rb +11 -8
  40. data/lib/cucumber/version.rb +1 -1
  41. data/rails_generators/cucumber/cucumber_generator.rb +12 -2
  42. data/rails_generators/cucumber/templates/cucumber.rake +1 -1
  43. data/rails_generators/cucumber/templates/cucumber_environment.rb +6 -4
  44. data/rails_generators/cucumber/templates/env.rb +10 -3
  45. data/rails_generators/cucumber/templates/spork_env.rb +36 -0
  46. data/rails_generators/cucumber/templates/webrat_steps.rb +8 -0
  47. data/spec/cucumber/cli/configuration_spec.rb +56 -1
  48. data/spec/cucumber/cli/drb_client_spec.rb +42 -0
  49. data/spec/cucumber/cli/main_spec.rb +64 -19
  50. metadata +12 -2
@@ -5,6 +5,7 @@ require 'cucumber/parser'
5
5
  require 'cucumber/formatter/color_io'
6
6
  require 'cucumber/cli/language_help_formatter'
7
7
  require 'cucumber/cli/configuration'
8
+ require 'cucumber/cli/drb_client'
8
9
 
9
10
  module Cucumber
10
11
  module Cli
@@ -32,6 +33,14 @@ module Cucumber
32
33
  end
33
34
 
34
35
  def execute!(step_mother)
36
+ if configuration.drb?
37
+ if DRbClient.run(@args, @error_stream, @out_stream)
38
+ return false
39
+ else
40
+ @error_stream.puts "WARNING: No DRb server is running. Running features locally:"
41
+ configuration.parse!(@args)
42
+ end
43
+ end
35
44
  configuration.load_language
36
45
  step_mother.options = configuration.options
37
46
 
@@ -6,7 +6,7 @@ module Cucumber
6
6
  class ColorIO
7
7
  extend Forwardable
8
8
  def_delegators :@kernel, :puts, :print # win32console colours only work when sent to Kernel
9
- def_delegators :@stdout, :flush, :tty?
9
+ def_delegators :@stdout, :flush, :tty?, :write
10
10
 
11
11
  def initialize
12
12
  @kernel = Kernel
@@ -20,4 +20,4 @@ module Cucumber
20
20
  end
21
21
  end
22
22
  end
23
- end
23
+ end
@@ -66,9 +66,7 @@ module Cucumber
66
66
  end
67
67
 
68
68
  def print_exception(e, status, indent)
69
- if @options[:strict] || !(Undefined === e) || e.nested?
70
- @io.puts(format_string("#{e.message} (#{e.class})\n#{e.backtrace.join("\n")}".indent(indent), status))
71
- end
69
+ @io.puts(format_string("#{e.message} (#{e.class})\n#{e.backtrace.join("\n")}".indent(indent), status))
72
70
  end
73
71
 
74
72
  def print_snippets(options)
@@ -15,7 +15,12 @@ module Cucumber
15
15
 
16
16
  def initialize(step_mother, io, options)
17
17
  super(step_mother)
18
- @builder = Builder::XmlMarkup.new(:target => io, :indent => 2)
18
+ @options = options
19
+ @builder = create_builder(io)
20
+ end
21
+
22
+ def create_builder(io)
23
+ Builder::XmlMarkup.new(:target => io, :indent => 2)
19
24
  end
20
25
 
21
26
  def visit_features(features)
@@ -42,7 +47,18 @@ module Cucumber
42
47
  end
43
48
  end
44
49
 
50
+ def visit_comment(comment)
51
+ @builder.pre(:class => 'comment') do
52
+ super
53
+ end
54
+ end
55
+
56
+ def visit_comment_line(comment_line)
57
+ @builder.text!(comment_line.strip + "\n")
58
+ end
59
+
45
60
  def visit_feature(feature)
61
+ @exceptions = []
46
62
  @builder.div(:class => 'feature') do
47
63
  super
48
64
  end
@@ -54,7 +70,9 @@ module Cucumber
54
70
 
55
71
  def visit_feature_name(name)
56
72
  lines = name.split(/\r?\n/)
57
- @builder.h2(lines[0])
73
+ @builder.h2 do |h2|
74
+ @builder.span(lines[0], :class => 'val')
75
+ end
58
76
  @builder.p do
59
77
  lines[1..-1].each do |line|
60
78
  @builder.text!(line.strip)
@@ -65,17 +83,27 @@ module Cucumber
65
83
 
66
84
  def visit_background(background)
67
85
  @builder.div(:class => 'background') do
86
+ @in_background = true
68
87
  super
88
+ @in_background = nil
69
89
  end
70
90
  end
71
91
 
72
92
  def visit_background_name(keyword, name, file_colon_line, source_indent)
73
93
  @listing_background = true
74
- @builder.h3("#{keyword} #{name}")
94
+ @builder.h3 do |h3|
95
+ @builder.span(keyword, :class => 'keyword')
96
+ @builder.text!(' ')
97
+ @builder.span(name, :class => 'val')
98
+ end
75
99
  end
76
100
 
77
101
  def visit_feature_element(feature_element)
78
- @builder.div(:class => 'scenario') do
102
+ css_class = {
103
+ Ast::Scenario => 'scenario',
104
+ Ast::ScenarioOutline => 'scenario outline'
105
+ }[feature_element.class]
106
+ @builder.div(:class => css_class) do
79
107
  super
80
108
  end
81
109
  @open_step_list = true
@@ -83,7 +111,11 @@ module Cucumber
83
111
 
84
112
  def visit_scenario_name(keyword, name, file_colon_line, source_indent)
85
113
  @listing_background = false
86
- @builder.h3("#{keyword} #{name}")
114
+ @builder.h3 do
115
+ @builder.span(keyword, :class => 'keyword')
116
+ @builder.text!(' ')
117
+ @builder.span(name, :class => 'val')
118
+ end
87
119
  end
88
120
 
89
121
  def visit_outline_table(outline_table)
@@ -94,8 +126,18 @@ module Cucumber
94
126
  @outline_row = nil
95
127
  end
96
128
 
129
+ def visit_examples(examples)
130
+ @builder.div(:class => 'examples') do
131
+ super(examples)
132
+ end
133
+ end
134
+
97
135
  def visit_examples_name(keyword, name)
98
- @builder.h4("#{keyword} #{name}")
136
+ @builder.h4 do
137
+ @builder.span(keyword, :class => 'keyword')
138
+ @builder.text!(' ')
139
+ @builder.span(name, :class => 'val')
140
+ end
99
141
  end
100
142
 
101
143
  def visit_steps(steps)
@@ -110,6 +152,11 @@ module Cucumber
110
152
  end
111
153
 
112
154
  def visit_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
155
+ if exception
156
+ return if @exceptions.index(exception)
157
+ @exceptions << exception
158
+ end
159
+ return if status != :failed && @in_background ^ background
113
160
  @status = status
114
161
  @builder.li(:id => @step_id, :class => "step #{status}") do
115
162
  super(keyword, step_match, multiline_arg, status, exception, source_indent, background)
@@ -143,8 +190,8 @@ module Cucumber
143
190
  end
144
191
 
145
192
  def visit_py_string(string)
146
- @builder.pre(:class => @status) do |pre|
147
- pre << string
193
+ @builder.pre(:class => 'val') do |pre|
194
+ @builder.text!(string)
148
195
  end
149
196
  end
150
197
 
@@ -168,8 +215,8 @@ module Cucumber
168
215
 
169
216
  def visit_table_cell_value(value, width, status)
170
217
  cell_type = @outline_row == 0 ? :th : :td
171
- attributes = {:id => "#{@row_id}_#{@col_index}"}
172
- attributes[:class] = status if status
218
+ attributes = {:id => "#{@row_id}_#{@col_index}", :class => 'val'}
219
+ attributes[:class] += " #{status}" if status
173
220
  build_cell(cell_type, value, attributes)
174
221
  @col_index += 1
175
222
  end
@@ -181,9 +228,13 @@ module Cucumber
181
228
  protected
182
229
 
183
230
  def build_step(keyword, step_match, status)
184
- step_name = step_match.format_args(lambda{|param| %{<span class="#{status}_param">#{param}</span>}})
231
+ step_name = step_match.format_args(lambda{|param| %{<span class="param">#{param}</span>}})
185
232
  @builder.div do |div|
186
- div << h("#{keyword} #{step_name}").gsub(/&lt;span class=&quot;(.*?)&quot;&gt;/, '<span class="\1">').gsub(/&lt;\/span&gt;/, '</span>')
233
+ @builder.span(keyword, :class => 'keyword')
234
+ @builder.text!(' ')
235
+ @builder.span(:class => 'step val') do |name|
236
+ name << h(step_name).gsub(/&lt;span class=&quot;(.*?)&quot;&gt;/, '<span class="\1">').gsub(/&lt;\/span&gt;/, '</span>')
237
+ end
187
238
  end
188
239
  end
189
240
 
@@ -11,9 +11,9 @@ module Cucumber
11
11
 
12
12
  def initialize(step_mother, io, options)
13
13
  super(step_mother)
14
+ raise "You *must* specify --out DIR for the junit formatter" unless String === io && File.directory?(io)
14
15
  @reportdir = io
15
- raise "You *must* specify --out DIR for the junit formatter" unless @reportdir
16
- raise "Use --out DIR (not --out FILE) for the junit formatter" if File === @reportdir
16
+ @options = options
17
17
  end
18
18
 
19
19
  def visit_feature(feature)
@@ -18,8 +18,8 @@ module Cucumber
18
18
  @io = io
19
19
  @options = options
20
20
  @delim = delim
21
- @indent = 0
22
21
  @exceptions = []
22
+ @indent = 0
23
23
  end
24
24
 
25
25
  def visit_features(features)
@@ -28,6 +28,7 @@ module Cucumber
28
28
  end
29
29
 
30
30
  def visit_feature(feature)
31
+ @exceptions = []
31
32
  @indent = 0
32
33
  if @options[:autoformat]
33
34
  file = File.join(@options[:autoformat], feature.file)
@@ -12,6 +12,7 @@ module Cucumber
12
12
  def initialize(step_mother, io, options)
13
13
  super(step_mother)
14
14
  @io = io
15
+ @options = options
15
16
  @file_names = []
16
17
  @file_colon_lines = Hash.new{|h,k| h[k] = []}
17
18
  end
@@ -5,6 +5,7 @@ module Cucumber
5
5
  def initialize(step_mother, io, options)
6
6
  super(step_mother)
7
7
  @io = io
8
+ @options = options
8
9
  @counts = Hash.new{|h,k| h[k] = 0}
9
10
  end
10
11
 
@@ -2,7 +2,9 @@ require 'cucumber/rails/world'
2
2
  require 'spec/expectations'
3
3
  require 'spec/rails/matchers'
4
4
 
5
- Cucumber::Rails::World.class_eval do
6
- include Spec::Matchers
7
- include Spec::Rails::Matchers
5
+ [Cucumber::Rails::World, ActionController::Integration::Session].each do |klass|
6
+ klass.class_eval do
7
+ include Spec::Matchers
8
+ include Spec::Rails::Matchers
9
+ end
8
10
  end
@@ -90,7 +90,7 @@ module Cucumber
90
90
  class_eval <<-EOF, __FILE__, __LINE__ + 1
91
91
  def #{attribute}=(value)
92
92
  @#{attribute} = value
93
- warn("Cucumber::Rake::Task##{attribute} is deprecated and will be removed in 0.4.0. Please use profiles for complex settings: http://wiki.github.com/aslakhellesoy/cucumber/using-rake#profiles")
93
+ warn("\nWARNING: Cucumber::Rake::Task##{attribute} is deprecated and will be removed in 0.4.0. Please use profiles for complex settings: http://wiki.github.com/aslakhellesoy/cucumber/using-rake#profiles\n")
94
94
  end
95
95
  EOF
96
96
  end
@@ -1,11 +1,15 @@
1
1
  module Cucumber
2
2
  class StepMatch
3
- attr_reader :step_definition, :args, :step_name
3
+ attr_reader :step_definition, :args
4
4
 
5
5
  def initialize(step_definition, step_name, formatted_step_name, args)
6
6
  @step_definition, @step_name, @formatted_step_name, @args = step_definition, step_name, formatted_step_name, args
7
7
  end
8
-
8
+
9
+ def name
10
+ @formatted_step_name
11
+ end
12
+
9
13
  def invoke(world, multiline_arg)
10
14
  all_args = @args.dup
11
15
  all_args << multiline_arg if multiline_arg
@@ -100,6 +100,10 @@ module Cucumber
100
100
 
101
101
  attr_writer :snippet_generator, :options, :visitor
102
102
 
103
+ def options
104
+ @options ||= {}
105
+ end
106
+
103
107
  def step_visited(step)
104
108
  steps << step unless steps.index(step)
105
109
  end
@@ -235,6 +239,13 @@ module Cucumber
235
239
  end
236
240
  end
237
241
 
242
+ def clear!
243
+ step_definitions.clear
244
+ hooks.clear
245
+ steps.clear
246
+ scenarios.clear
247
+ end
248
+
238
249
  def step_definitions
239
250
  @step_definitions ||= []
240
251
  end
@@ -274,10 +285,6 @@ module Cucumber
274
285
  @max_step_definition_length ||= step_definitions.map{|step_definition| step_definition.text_length}.max
275
286
  end
276
287
 
277
- def options
278
- @options || {}
279
- end
280
-
281
288
  # Creates a new world instance
282
289
  def new_world!
283
290
  return if options[:dry_run]
@@ -351,9 +358,5 @@ module Cucumber
351
358
  def scenario_visited(scenario)
352
359
  scenarios << scenario unless scenarios.index(scenario)
353
360
  end
354
-
355
- def options
356
- @options || {}
357
- end
358
361
  end
359
362
  end
@@ -2,7 +2,7 @@ module Cucumber #:nodoc:
2
2
  class VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 3
5
- TINY = 9
5
+ TINY = 10
6
6
  PATCH = nil # Set to nil for official release
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PATCH].compact.join('.')
@@ -19,11 +19,17 @@ class CucumberGenerator < Rails::Generator::Base
19
19
  m.gsub_file 'config/database.yml', /\z/, "\ncucumber:\n <<: *TEST"
20
20
 
21
21
  m.directory 'features/support'
22
- m.template 'env.rb', 'features/support/env.rb'
22
+
23
+ if options[:spork]
24
+ m.template 'spork_env.rb', 'features/support/env.rb'
25
+ else
26
+ m.template 'env.rb', 'features/support/env.rb'
27
+ end
28
+
23
29
  m.file 'paths.rb', 'features/support/paths.rb'
24
30
 
25
31
  m.directory 'lib/tasks'
26
- m.file 'cucumber.rake', 'lib/tasks/cucumber.rake'
32
+ m.template 'cucumber.rake', 'lib/tasks/cucumber.rake'
27
33
 
28
34
  m.file 'cucumber', 'script/cucumber', {
29
35
  :chmod => 0755, :shebang => options[:shebang] == DEFAULT_SHEBANG ? nil : options[:shebang]
@@ -51,6 +57,10 @@ protected
51
57
  opt.on('--testunit', 'Setup cucumber for use with test/unit') do |value|
52
58
  options[:framework] = :testunit
53
59
  end
60
+
61
+ opt.on('--spork', 'Setup cucumber for use with Spork') do |value|
62
+ options[:spork] = true
63
+ end
54
64
  end
55
65
 
56
66
  end
@@ -5,7 +5,7 @@ begin
5
5
 
6
6
  Cucumber::Rake::Task.new(:features) do |t|
7
7
  t.fork = true
8
- t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'pretty')]
8
+ t.cucumber_opts = [<%= options[:spork] ? "'--drb', " : "" %>'--format', (ENV['CUCUMBER_FORMAT'] || 'pretty')]
9
9
  end
10
10
  task :features => 'db:test:prepare'
11
11
  rescue LoadError
@@ -15,7 +15,9 @@ config.action_controller.allow_forgery_protection = false
15
15
  # ActionMailer::Base.deliveries array.
16
16
  config.action_mailer.delivery_method = :test
17
17
 
18
- config.gem "cucumber", :lib => false, :version => ">=<%= cucumber_version %>"
19
- config.gem "webrat", :lib => false, :version => ">=0.4.4"
20
- config.gem "rspec", :lib => false, :version => ">=1.2.6"
21
- config.gem "rspec-rails", :lib => 'spec/rails', :version => ">=1.2.6"
18
+ config.gem "cucumber", :lib => false, :version => ">=<%= cucumber_version %>" unless File.directory?(File.join(Rails.root, 'vendor/plugins/cucumber'))
19
+ config.gem "webrat", :lib => false, :version => ">=0.4.4" unless File.directory?(File.join(Rails.root, 'vendor/plugins/webrat'))
20
+ <% if framework == :rspec -%>
21
+ config.gem "rspec", :lib => false, :version => ">=1.2.6" unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec'))
22
+ config.gem "rspec-rails", :lib => 'spec/rails', :version => ">=1.2.6" unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec-rails'))
23
+ <% end %>
@@ -2,10 +2,17 @@
2
2
  ENV["RAILS_ENV"] ||= "cucumber"
3
3
  require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
4
4
  require 'cucumber/rails/world'
5
- require 'cucumber/formatter/unicode' # Comment out this line if you don't want Cucumber Unicode support
5
+
6
+ # Comment out the next line if you don't want Cucumber Unicode support
7
+ require 'cucumber/formatter/unicode'
8
+
9
+ # Comment out the next line if you don't want transactions to
10
+ # open/roll back around each scenario
6
11
  Cucumber::Rails.use_transactional_fixtures
7
- Cucumber::Rails.bypass_rescue # Comment out this line if you want Rails own error handling
8
- # (e.g. rescue_action_in_public / rescue_responses / rescue_from)
12
+
13
+ # Comment out the next line if you want Rails' own error handling
14
+ # (e.g. rescue_action_in_public / rescue_responses / rescue_from)
15
+ Cucumber::Rails.bypass_rescue
9
16
 
10
17
  require 'webrat'
11
18
 
@@ -0,0 +1,36 @@
1
+ require 'rubygems'
2
+ require 'spork'
3
+
4
+ Spork.prefork do
5
+ # Sets up the Rails environment for Cucumber
6
+ ENV["RAILS_ENV"] ||= "cucumber"
7
+ require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
8
+
9
+ require 'webrat'
10
+
11
+ Webrat.configure do |config|
12
+ config.mode = :rails
13
+ end
14
+
15
+ require 'webrat/core/matchers'
16
+ require 'cucumber'
17
+
18
+ # Comment out the next line if you don't want Cucumber Unicode support
19
+ require 'cucumber/formatter/unicode'
20
+
21
+ require 'spec/rails'
22
+ require 'cucumber/rails/rspec'
23
+ end
24
+
25
+ Spork.each_run do
26
+ # This code will be run each time you run your specs.
27
+ require 'cucumber/rails/world'
28
+
29
+ # Comment out the next line if you don't want transactions to
30
+ # open/roll back around each scenario
31
+ Cucumber::Rails.use_transactional_fixtures
32
+
33
+ # Comment out the next line if you want Rails' own error handling
34
+ # (e.g. rescue_action_in_public / rescue_responses / rescue_from)
35
+ Cucumber::Rails.bypass_rescue
36
+ end