cucumber 0.3.9 → 0.3.10

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