cucumber 0.3.95 → 0.3.96

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/History.txt +21 -0
  2. data/Manifest.txt +9 -3
  3. data/examples/sinatra/features/support/env.rb +1 -3
  4. data/features/cucumber_cli.feature +1 -0
  5. data/features/drb_server_integration.feature +56 -3
  6. data/features/junit_formatter.feature +23 -12
  7. data/features/step_definitions/cucumber_steps.rb +13 -2
  8. data/features/support/env.rb +19 -3
  9. data/lib/cucumber/ast/feature_element.rb +1 -1
  10. data/lib/cucumber/ast/step.rb +1 -1
  11. data/lib/cucumber/ast/step_invocation.rb +3 -2
  12. data/lib/cucumber/cli/configuration.rb +9 -25
  13. data/lib/cucumber/cli/drb_client.rb +7 -3
  14. data/lib/cucumber/cli/language_help_formatter.rb +4 -4
  15. data/lib/cucumber/cli/main.rb +26 -46
  16. data/lib/cucumber/cli/options.rb +3 -0
  17. data/lib/cucumber/constantize.rb +28 -0
  18. data/lib/cucumber/feature_file.rb +3 -3
  19. data/lib/cucumber/formatter/junit.rb +13 -9
  20. data/lib/cucumber/formatter/pretty.rb +2 -2
  21. data/lib/cucumber/language_support/hook_methods.rb +9 -0
  22. data/lib/cucumber/language_support/language_methods.rb +47 -0
  23. data/lib/cucumber/language_support/step_definition_methods.rb +44 -0
  24. data/lib/cucumber/parser/natural_language.rb +72 -0
  25. data/lib/cucumber/rb_support/rb_dsl.rb +73 -0
  26. data/lib/cucumber/rb_support/rb_hook.rb +19 -0
  27. data/lib/cucumber/rb_support/rb_language.rb +129 -0
  28. data/lib/cucumber/rb_support/rb_step_definition.rb +56 -0
  29. data/lib/cucumber/step_match.rb +2 -2
  30. data/lib/cucumber/step_mother.rb +87 -206
  31. data/lib/cucumber/version.rb +1 -1
  32. data/lib/cucumber/webrat/element_locator.rb +7 -7
  33. data/lib/cucumber/world.rb +28 -8
  34. data/rails_generators/cucumber/templates/cucumber_environment.rb +2 -2
  35. data/rails_generators/cucumber/templates/spork_env.rb +0 -2
  36. data/rails_generators/cucumber/templates/webrat_steps.rb +17 -0
  37. data/spec/cucumber/ast/background_spec.rb +8 -5
  38. data/spec/cucumber/ast/feature_factory.rb +4 -5
  39. data/spec/cucumber/ast/feature_spec.rb +7 -1
  40. data/spec/cucumber/ast/scenario_outline_spec.rb +10 -6
  41. data/spec/cucumber/ast/scenario_spec.rb +8 -3
  42. data/spec/cucumber/ast/step_collection_spec.rb +2 -2
  43. data/spec/cucumber/cli/configuration_spec.rb +15 -0
  44. data/spec/cucumber/cli/drb_client_spec.rb +35 -1
  45. data/spec/cucumber/cli/main_spec.rb +5 -4
  46. data/spec/cucumber/cli/options_spec.rb +6 -0
  47. data/spec/cucumber/parser/feature_parser_spec.rb +6 -5
  48. data/spec/cucumber/parser/table_parser_spec.rb +1 -1
  49. data/spec/cucumber/step_definition_spec.rb +26 -25
  50. data/spec/cucumber/step_mother_spec.rb +46 -41
  51. data/spec/cucumber/world/pending_spec.rb +4 -5
  52. metadata +11 -5
  53. data/lib/cucumber/cli/rb_step_def_loader.rb +0 -14
  54. data/lib/cucumber/parser/i18n/language.rb +0 -87
  55. data/lib/cucumber/step_definition.rb +0 -122
@@ -0,0 +1,73 @@
1
+ require 'cucumber/rb_support/rb_hook'
2
+
3
+ module Cucumber
4
+ module RbSupport
5
+ # This module defines the methods you can use to define pure Ruby
6
+ # Step Definitions and Hooks. This module is mixed into the toplevel
7
+ # object.
8
+ module RbDsl
9
+ class << self
10
+ attr_accessor :step_mother, :rb_language
11
+
12
+ def alias_adverb(adverb)
13
+ alias_method adverb, :register_rb_step_definition
14
+ end
15
+ end
16
+
17
+ # Registers any number of +world_modules+ (Ruby Modules) and/or a Proc.
18
+ # The +proc+ will be executed once before each scenario to create an
19
+ # Object that the scenario's steps will run within. Any +world_modules+
20
+ # will be mixed into this Object (via Object#extend).
21
+ #
22
+ # This method is typically called from one or more Ruby scripts under
23
+ # <tt>features/support</tt>. You can call this method as many times as you
24
+ # like (to register more modules), but if you try to register more than
25
+ # one Proc you will get an error.
26
+ #
27
+ # Cucumber will not yield anything to the +proc+. Examples:
28
+ #
29
+ # World do
30
+ # MyClass.new
31
+ # end
32
+ #
33
+ # World(MyModule)
34
+ #
35
+ def World(*world_modules, &proc)
36
+ RbDsl.rb_language.build_world_factory(*world_modules, &proc)
37
+ end
38
+
39
+ # Registers a Before proc. You can call this method as many times as you
40
+ # want (typically from ruby scripts under <tt>support</tt>).
41
+ def Before(*tag_names, &proc)
42
+ RbDsl.step_mother.register_hook(:before, RbHook.new(RbDsl.rb_language, tag_names, proc))
43
+ end
44
+
45
+ def After(*tag_names, &proc)
46
+ RbDsl.step_mother.register_hook(:after, RbHook.new(RbDsl.rb_language, tag_names, proc))
47
+ end
48
+
49
+ def AfterStep(*tag_names, &proc)
50
+ RbDsl.step_mother.register_hook(:after_step, RbHook.new(RbDsl.rb_language, tag_names, proc))
51
+ end
52
+
53
+ # Registers a new Ruby StepDefinition.
54
+ # This method is aliased
55
+ # to <tt>Given</tt>, <tt>When</tt> and <tt>Then</tt>, and
56
+ # also to the i18n translations whenever a feature of a
57
+ # new language is loaded.
58
+ #
59
+ # See Cucumber#alias_steps for details on how to
60
+ # create your own aliases.
61
+ #
62
+ # The +&proc+ gets executed in the context of a <tt>world</tt>
63
+ # object, which is defined by #World. A new <tt>world</tt>
64
+ # object is created for each scenario and is shared across
65
+ # step definitions within that scenario.
66
+ def register_rb_step_definition(regexp, &proc)
67
+ RbDsl.step_mother.register_step_definition(RbStepDefinition.new(RbDsl.rb_language, regexp, &proc))
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ extend(Cucumber::RbSupport::RbDsl)
@@ -0,0 +1,19 @@
1
+ module Cucumber
2
+ module RbSupport
3
+ class RbHook
4
+ include LanguageSupport::HookMethods
5
+
6
+ attr_reader :tag_names
7
+
8
+ def initialize(rb_language, tag_names, proc)
9
+ @rb_language = rb_language
10
+ @tag_names = tag_names
11
+ @proc = proc
12
+ end
13
+
14
+ def invoke(location, scenario)
15
+ @rb_language.current_world.cucumber_instance_exec(false, location, scenario, &@proc)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,129 @@
1
+ require 'cucumber/rb_support/rb_dsl'
2
+ require 'cucumber/rb_support/rb_step_definition'
3
+
4
+ module Cucumber
5
+ module RbSupport
6
+ class NilWorld < StandardError
7
+ def initialize
8
+ super("World procs should never return nil")
9
+ end
10
+ end
11
+
12
+ class MultipleWorld < StandardError
13
+ def initialize(first_proc, second_proc)
14
+ message = "You can only pass a proc to #World once, but it's happening\n"
15
+ message << "in 2 places:\n\n"
16
+ message << first_proc.backtrace_line('World') << "\n"
17
+ message << second_proc.backtrace_line('World') << "\n\n"
18
+ message << "Use Ruby modules instead to extend your worlds. See the Cucumber::StepMother#World RDoc\n"
19
+ message << "or http://wiki.github.com/aslakhellesoy/cucumber/a-whole-new-world.\n\n"
20
+ super(message)
21
+ end
22
+ end
23
+
24
+ class RbLanguage
25
+ include LanguageSupport::LanguageMethods
26
+ attr_reader :current_world, :step_mother
27
+
28
+ def initialize(step_mother)
29
+ @step_mother = step_mother
30
+ RbDsl.step_mother = step_mother
31
+ RbDsl.rb_language = self
32
+ end
33
+
34
+ def load_step_def_file(step_def_file)
35
+ begin
36
+ require step_def_file
37
+ rescue LoadError => e
38
+ e.message << "\nFailed to load #{step_def_file}"
39
+ raise e
40
+ end
41
+ end
42
+
43
+ def build_world_factory(*world_modules, &proc)
44
+ if(proc)
45
+ raise MultipleWorld.new(@world_proc, proc) if @world_proc
46
+ @world_proc = proc
47
+ end
48
+ @world_modules ||= []
49
+ @world_modules += world_modules
50
+ end
51
+
52
+ def begin_scenario
53
+ create_world
54
+ extend_world
55
+ connect_world(@step_mother)
56
+ end
57
+
58
+ def end_scenario
59
+ @current_world = nil
60
+ end
61
+
62
+ def snippet_text(step_keyword, step_name, multiline_arg_class = nil)
63
+ escaped = Regexp.escape(step_name).gsub('\ ', ' ').gsub('/', '\/')
64
+ escaped = escaped.gsub(PARAM_PATTERN, ESCAPED_PARAM_PATTERN)
65
+
66
+ n = 0
67
+ block_args = escaped.scan(ESCAPED_PARAM_PATTERN).map do |a|
68
+ n += 1
69
+ "arg#{n}"
70
+ end
71
+ block_args << multiline_arg_class.default_arg_name unless multiline_arg_class.nil?
72
+ block_arg_string = block_args.empty? ? "" : " |#{block_args.join(", ")}|"
73
+ multiline_class_comment = ""
74
+ if(multiline_arg_class == Ast::Table)
75
+ multiline_class_comment = "# #{multiline_arg_class.default_arg_name} is a #{multiline_arg_class.to_s}\n "
76
+ end
77
+
78
+ "#{step_keyword} /^#{escaped}$/ do#{block_arg_string}\n #{multiline_class_comment}pending\nend"
79
+ end
80
+
81
+ def alias_adverbs(adverbs)
82
+ adverbs.each do |adverb|
83
+ RbDsl.alias_adverb(adverb)
84
+ World.alias_adverb(adverb)
85
+ end
86
+ end
87
+
88
+ private
89
+
90
+ PARAM_PATTERN = /"([^\"]*)"/
91
+ ESCAPED_PARAM_PATTERN = '"([^\\"]*)"'
92
+
93
+ def create_world
94
+ if(@world_proc)
95
+ @current_world = @world_proc.call
96
+ check_nil(@current_world, @world_proc)
97
+ else
98
+ @current_world = Object.new
99
+ end
100
+ end
101
+
102
+ def extend_world
103
+ @current_world.extend(World)
104
+ @current_world.extend(::Spec::Matchers) if defined?(::Spec::Matchers)
105
+ (@world_modules || []).each do |mod|
106
+ @current_world.extend(mod)
107
+ end
108
+ end
109
+
110
+ def connect_world(step_mother)
111
+ @current_world.__cucumber_step_mother = step_mother
112
+ end
113
+
114
+ def check_nil(o, proc)
115
+ if o.nil?
116
+ begin
117
+ raise NilWorld.new
118
+ rescue NilWorld => e
119
+ e.backtrace.clear
120
+ e.backtrace.push(proc.backtrace_line("World"))
121
+ raise e
122
+ end
123
+ else
124
+ o
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,56 @@
1
+ require 'cucumber/step_match'
2
+ require 'cucumber/core_ext/string'
3
+ require 'cucumber/core_ext/proc'
4
+
5
+ module Cucumber
6
+ # A Step Definition holds a Regexp and a Proc, and is created
7
+ # by calling <tt>Given</tt>, <tt>When</tt> or <tt>Then</tt>
8
+ # in the <tt>step_definitions</tt> ruby files - for example:
9
+ #
10
+ # Given /I have (\d+) cucumbers in my belly/ do
11
+ # # some code here
12
+ # end
13
+ #
14
+ class RbStepDefinition
15
+ include LanguageSupport::StepDefinitionMethods
16
+
17
+ class MissingProc < StandardError
18
+ def message
19
+ "Step definitions must always have a proc"
20
+ end
21
+ end
22
+
23
+ attr_reader :proc
24
+
25
+ def initialize(rb_language, pattern, &proc)
26
+ raise MissingProc if proc.nil?
27
+ if String === pattern
28
+ p = pattern.gsub(/\$\w+/, '(.*)') # Replace $var with (.*)
29
+ pattern = Regexp.new("^#{p}$")
30
+ end
31
+ @rb_language, @regexp, @proc = rb_language, pattern, proc
32
+ end
33
+
34
+ def regexp
35
+ @regexp
36
+ end
37
+
38
+ def invoke(args)
39
+ args = args.map{|arg| Ast::PyString === arg ? arg.to_s : arg}
40
+ begin
41
+ @rb_language.current_world.cucumber_instance_exec(true, regexp.inspect, *args, &@proc)
42
+ rescue Cucumber::ArityMismatchError => e
43
+ e.backtrace.unshift(self.backtrace_line)
44
+ raise e
45
+ end
46
+ end
47
+
48
+ def file_colon_line
49
+ @proc.file_colon_line
50
+ end
51
+
52
+ def file
53
+ @file ||= file_colon_line.split(':')[0]
54
+ end
55
+ end
56
+ end
@@ -10,10 +10,10 @@ module Cucumber
10
10
  @formatted_step_name
11
11
  end
12
12
 
13
- def invoke(world, multiline_arg)
13
+ def invoke(multiline_arg)
14
14
  all_args = @args.dup
15
15
  all_args << multiline_arg if multiline_arg
16
- @step_definition.invoke(world, all_args)
16
+ @step_definition.invoke(all_args)
17
17
  end
18
18
 
19
19
  def format_args(format = lambda{|a| a})
@@ -1,6 +1,10 @@
1
- require 'cucumber/step_definition'
1
+ require 'cucumber/constantize'
2
2
  require 'cucumber/world'
3
3
  require 'cucumber/core_ext/instance_exec'
4
+ require 'cucumber/parser/natural_language'
5
+ require 'cucumber/language_support/hook_methods'
6
+ require 'cucumber/language_support/language_methods'
7
+ require 'cucumber/language_support/step_definition_methods'
4
8
 
5
9
  module Cucumber
6
10
  class Undefined < StandardError
@@ -45,61 +49,56 @@ module Cucumber
45
49
  end
46
50
  end
47
51
 
48
- class NilWorld < StandardError
49
- def initialize
50
- super("World procs should never return nil")
51
- end
52
- end
53
-
54
- class MultipleWorld < StandardError
55
- def initialize(first_proc, second_proc)
56
- message = "You can only pass a proc to #World once, but it's happening\n"
57
- message << "in 2 places:\n\n"
58
- message << first_proc.backtrace_line('World') << "\n"
59
- message << second_proc.backtrace_line('World') << "\n\n"
60
- message << "Use Ruby modules instead to extend your worlds. See the Cucumber::StepMother#World RDoc\n"
61
- message << "or http://wiki.github.com/aslakhellesoy/cucumber/a-whole-new-world.\n\n"
62
- super(message)
63
- end
64
- end
65
-
66
52
  # This is the main interface for registering step definitions, which is done
67
53
  # from <tt>*_steps.rb</tt> files. This module is included right at the top-level
68
54
  # so #register_step_definition (and more interestingly - its aliases) are
69
55
  # available from the top-level.
70
- module StepMother
71
- class Hook
72
- def initialize(tag_names, proc)
73
- @tag_names = tag_names.map{|tag| Ast::Tags.strip_prefix(tag)}
74
- @proc = proc
75
- end
56
+ class StepMother
57
+ include Constantize
58
+
59
+ attr_writer :options, :visitor
76
60
 
77
- def matches_tag_names?(tag_names)
78
- @tag_names.empty? || (@tag_names & tag_names).any?
79
- end
61
+ def initialize
62
+ @programming_languages = []
63
+ @language_map = {}
64
+ load_natural_language('en')
65
+ end
80
66
 
81
- def execute_in(world, scenario, location, exception_fails_scenario = true)
82
- begin
83
- world.cucumber_instance_exec(false, location, scenario, &@proc)
84
- rescue Exception => exception
85
- if exception_fails_scenario
86
- scenario.fail!(exception)
87
- else
88
- raise
89
- end
90
- end
91
- end
67
+ # Loads and registers programming language implementation.
68
+ # Instances are cached, so calling with the same argument
69
+ # twice will return the same instance.
70
+ #
71
+ # Raises an exception if the language can't be loaded.
72
+ #
73
+ def load_programming_language(ext)
74
+ return @language_map[ext] if @language_map[ext]
75
+ programming_language_class = constantize("Cucumber::#{ext.capitalize}Support::#{ext.capitalize}Language")
76
+ programming_language = programming_language_class.new(self)
77
+ programming_language.alias_adverbs(@adverbs || [])
78
+ @programming_languages << programming_language
79
+ @language_map[ext] = programming_language
80
+ programming_language
81
+ end
82
+
83
+ # Loads a natural language. This has the effect of aliasing
84
+ # Step Definition keywords for all of the registered programming
85
+ # languages (if they support aliasing). See #load_programming_language
86
+ #
87
+ def load_natural_language(lang)
88
+ Parser::NaturalLanguage.get(self, lang)
92
89
  end
93
90
 
94
- class << self
95
- def alias_adverb(adverb)
96
- adverb = adverb.gsub(/\s/, '')
97
- alias_method adverb, :register_step_definition
91
+ # Registers a StepDefinition. This can be a Ruby StepDefintion,
92
+ # or any other kind of object that implements the StepDefintion
93
+ # contract (API).
94
+ def register_step_definition(step_definition)
95
+ step_definitions.each do |already|
96
+ raise Redundant.new(already, step_definition) if already.same_regexp?(step_definition.regexp)
98
97
  end
98
+ step_definitions << step_definition
99
+ step_definition
99
100
  end
100
101
 
101
- attr_writer :snippet_generator, :options, :visitor
102
-
103
102
  def options
104
103
  @options ||= {}
105
104
  end
@@ -117,6 +116,10 @@ module Cucumber
117
116
  end
118
117
  end
119
118
 
119
+ def announce(msg)
120
+ @visitor.announce(msg)
121
+ end
122
+
120
123
  def scenarios(status = nil)
121
124
  @scenarios ||= []
122
125
  if(status)
@@ -126,44 +129,8 @@ module Cucumber
126
129
  end
127
130
  end
128
131
 
129
- # Registers a new StepDefinition. This method is aliased
130
- # to <tt>Given</tt>, <tt>When</tt> and <tt>Then</tt>, and
131
- # also to the i18n translations whenever a feature of a
132
- # new language is loaded.
133
- #
134
- # See Cucumber#alias_steps for details on how to
135
- # create your own aliases.
136
- #
137
- # The +&proc+ gets executed in the context of a <tt>world</tt>
138
- # object, which is defined by #World. A new <tt>world</tt>
139
- # object is created for each scenario and is shared across
140
- # step definitions within that scenario.
141
- def register_step_definition(regexp, &proc)
142
- step_definition = StepDefinition.new(regexp, &proc)
143
- step_definitions.each do |already|
144
- raise Redundant.new(already, step_definition) if already.match(regexp)
145
- end
146
- step_definitions << step_definition
147
- step_definition
148
- end
149
-
150
- # Registers a Before proc. You can call this method as many times as you
151
- # want (typically from ruby scripts under <tt>support</tt>).
152
- def Before(*tag_names, &proc)
153
- register_hook(:before, tag_names, proc)
154
- end
155
-
156
- def After(*tag_names, &proc)
157
- register_hook(:after, tag_names, proc)
158
- end
159
-
160
- def AfterStep(*tag_names, &proc)
161
- register_hook(:after_step, tag_names, proc)
162
- end
163
-
164
- def register_hook(phase, tags, proc)
165
- hook = Hook.new(tags, proc)
166
- hooks[phase] << hook
132
+ def register_hook(phase, hook)
133
+ hooks[phase.to_sym] << hook
167
134
  hook
168
135
  end
169
136
 
@@ -172,53 +139,7 @@ module Cucumber
172
139
  end
173
140
 
174
141
  def hooks_for(phase, scenario)
175
- hooks[phase].select{|hook| scenario.accept_hook?(hook)}
176
- end
177
-
178
- # Registers any number of +world_modules+ (Ruby Modules) and/or a Proc.
179
- # The +proc+ will be executed once before each scenario to create an
180
- # Object that the scenario's steps will run within. Any +world_modules+
181
- # will be mixed into this Object (via Object#extend).
182
- #
183
- # This method is typically called from one or more Ruby scripts under
184
- # <tt>features/support</tt>. You can call this method as many times as you
185
- # like (to register more modules), but if you try to register more than
186
- # one Proc you will get an error.
187
- #
188
- # Cucumber will not yield anything to the +proc+ (like it used to do before v0.3).
189
- #
190
- # In earlier versions of Cucumber (before 0.3) you could not register
191
- # any +world_modules+. Instead you would register several Proc objects (by
192
- # calling the method several times). The result of each +proc+ would be yielded
193
- # to the next +proc+. Example:
194
- #
195
- # World do |world| # NOT SUPPORTED FROM 0.3
196
- # MyClass.new
197
- # end
198
- #
199
- # World do |world| # NOT SUPPORTED FROM 0.3
200
- # world.extend(MyModule)
201
- # end
202
- #
203
- # From Cucumber 0.3 the recommended way to do this is:
204
- #
205
- # World do
206
- # MyClass.new
207
- # end
208
- #
209
- # World(MyModule)
210
- #
211
- def World(*world_modules, &proc)
212
- if(proc)
213
- raise MultipleWorld.new(@world_proc, proc) if @world_proc
214
- @world_proc = proc
215
- end
216
- @world_modules ||= []
217
- @world_modules += world_modules
218
- end
219
-
220
- def current_world
221
- @current_world
142
+ hooks[phase.to_sym].select{|hook| scenario.accept_hook?(hook)}
222
143
  end
223
144
 
224
145
  def step_match(step_name, formatted_step_name=nil)
@@ -257,108 +178,68 @@ module Cucumber
257
178
  end
258
179
 
259
180
  def snippet_text(step_keyword, step_name, multiline_arg_class)
260
- @snippet_generator.snippet_text(step_keyword, step_name, multiline_arg_class)
181
+ @programming_languages.map do |programming_language|
182
+ programming_language.snippet_text(step_keyword, step_name, multiline_arg_class)
183
+ end.join("\n")
261
184
  end
262
185
 
263
186
  def before_and_after(scenario, skip_hooks=false)
264
187
  before(scenario) unless skip_hooks
265
- @current_scenario = scenario
266
188
  yield scenario
267
- @current_scenario = nil
268
189
  after(scenario) unless skip_hooks
269
190
  scenario_visited(scenario)
270
191
  end
271
-
272
- def before(scenario)
273
- unless current_world
274
- new_world!
275
- execute_before(scenario)
276
- end
277
- end
278
-
279
- def after(scenario)
280
- execute_after(scenario)
281
- nil_world!
282
- end
283
-
284
- def after_step
285
- execute_after_step(@current_scenario)
286
- end
287
-
288
- private
289
192
 
290
- def max_step_definition_length
291
- @max_step_definition_length ||= step_definitions.map{|step_definition| step_definition.text_length}.max
193
+ def register_adverbs(adverbs)
194
+ @adverbs ||= []
195
+ @adverbs += adverbs
196
+ @adverbs.uniq!
197
+ @programming_languages.each do |programming_language|
198
+ programming_language.alias_adverbs(@adverbs)
199
+ end
292
200
  end
293
201
 
294
- # Creates a new world instance
295
- def new_world!
202
+ def begin_scenario
296
203
  return if options[:dry_run]
297
- create_world!
298
- extend_world
299
- connect_world
300
- @current_world
301
- end
302
-
303
- def create_world!
304
- if(@world_proc)
305
- @current_world = @world_proc.call
306
- check_nil(@current_world, @world_proc)
307
- else
308
- @current_world = Object.new
204
+ @programming_languages.each do |programming_language|
205
+ programming_language.begin_scenario
309
206
  end
310
207
  end
311
208
 
312
- def extend_world
313
- @current_world.extend(World)
314
- @current_world.extend(::Spec::Matchers) if defined?(::Spec::Matchers)
315
- (@world_modules || []).each do |mod|
316
- @current_world.extend(mod)
209
+ def end_scenario
210
+ return if options[:dry_run]
211
+ @programming_languages.each do |programming_language|
212
+ programming_language.end_scenario
317
213
  end
318
214
  end
319
-
320
- def connect_world
321
- @current_world.__cucumber_step_mother = self
322
- @current_world.__cucumber_visitor = @visitor
323
- end
324
-
325
- def check_nil(o, proc)
326
- if o.nil?
327
- begin
328
- raise NilWorld.new
329
- rescue NilWorld => e
330
- e.backtrace.clear
331
- e.backtrace.push(proc.backtrace_line("World"))
332
- raise e
333
- end
334
- else
335
- o
215
+
216
+ def before(scenario)
217
+ return if options[:dry_run] || @current_scenario
218
+ @current_scenario = scenario
219
+ @programming_languages.each do |programming_language|
220
+ programming_language.before(scenario)
336
221
  end
337
222
  end
338
-
339
- def nil_world!
340
- @current_world = nil
341
- end
342
-
343
- def execute_before(scenario)
223
+
224
+ def after(scenario)
225
+ @current_scenario = nil
344
226
  return if options[:dry_run]
345
- hooks_for(:before, scenario).each do |hook|
346
- hook.execute_in(@current_world, scenario, 'Before')
227
+ @programming_languages.each do |programming_language|
228
+ programming_language.after(scenario)
347
229
  end
348
230
  end
349
-
350
- def execute_after(scenario)
231
+
232
+ def after_step
351
233
  return if options[:dry_run]
352
- hooks_for(:after, scenario).each do |hook|
353
- hook.execute_in(@current_world, scenario, 'After')
234
+ @programming_languages.each do |programming_language|
235
+ programming_language.execute_after_step(@current_scenario)
354
236
  end
355
237
  end
238
+
239
+ private
356
240
 
357
- def execute_after_step(scenario)
358
- return if options[:dry_run]
359
- hooks_for(:after_step, scenario).each do |hook|
360
- hook.execute_in(@current_world, scenario, 'AfterStep', false)
361
- end
241
+ def max_step_definition_length
242
+ @max_step_definition_length ||= step_definitions.map{|step_definition| step_definition.text_length}.max
362
243
  end
363
244
 
364
245
  def scenario_visited(scenario)