Module: Cucumber::StepMother

Defined in:
lib/cucumber/step_mother.rb

Overview

This is the main interface for registering step definitions, which is done from *_steps.rb files. This module is included right at the top-level so #register_step_definition (and more interestingly - its aliases) are available from the top-level.

Defined Under Namespace

Classes: Hook

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#optionsObject



103
104
105
# File 'lib/cucumber/step_mother.rb', line 103

def options
  @options ||= {}
end

#snippet_generator=(value) ⇒ Object (writeonly)

Sets the attribute snippet_generator

Parameters:

  • value

    the value to set the attribute snippet_generator to.



101
102
103
# File 'lib/cucumber/step_mother.rb', line 101

def snippet_generator=(value)
  @snippet_generator = value
end

#visitor=(value) ⇒ Object (writeonly)

Sets the attribute visitor

Parameters:

  • value

    the value to set the attribute visitor to.



101
102
103
# File 'lib/cucumber/step_mother.rb', line 101

def visitor=(value)
  @visitor = value
end

Class Method Details

.alias_adverb(adverb) ⇒ Object



95
96
97
98
# File 'lib/cucumber/step_mother.rb', line 95

def alias_adverb(adverb)
  adverb = adverb.gsub(/\s/, '')
  alias_method adverb, :register_step_definition
end

Instance Method Details

#after(scenario) ⇒ Object



279
280
281
282
# File 'lib/cucumber/step_mother.rb', line 279

def after(scenario)
  execute_after(scenario)
  nil_world!
end

#After(*tag_names, &proc) ⇒ Object



156
157
158
# File 'lib/cucumber/step_mother.rb', line 156

def After(*tag_names, &proc)
  register_hook(:after, tag_names, proc)
end

#after_stepObject



284
285
286
# File 'lib/cucumber/step_mother.rb', line 284

def after_step
  execute_after_step(@current_scenario)
end

#AfterStep(*tag_names, &proc) ⇒ Object



160
161
162
# File 'lib/cucumber/step_mother.rb', line 160

def AfterStep(*tag_names, &proc)
  register_hook(:after_step, tag_names, proc)
end

#before(scenario) ⇒ Object



272
273
274
275
276
277
# File 'lib/cucumber/step_mother.rb', line 272

def before(scenario)
  unless current_world
    new_world!
    execute_before(scenario)
  end
end

#Before(*tag_names, &proc) ⇒ Object

Registers a Before proc. You can call this method as many times as you want (typically from ruby scripts under support).



152
153
154
# File 'lib/cucumber/step_mother.rb', line 152

def Before(*tag_names, &proc)
  register_hook(:before, tag_names, proc)
end

#before_and_after(scenario, skip_hooks = false) {|scenario| ... } ⇒ Object

Yields:

  • (scenario)


263
264
265
266
267
268
269
270
# File 'lib/cucumber/step_mother.rb', line 263

def before_and_after(scenario, skip_hooks=false)
  before(scenario) unless skip_hooks
  @current_scenario = scenario
  yield scenario
  @current_scenario = nil
  after(scenario) unless skip_hooks
  scenario_visited(scenario)
end

#best_matches(step_name, step_matches) ⇒ Object



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/cucumber/step_mother.rb', line 232

def best_matches(step_name, step_matches)
  no_groups      = step_matches.select {|step_match| step_match.args.length == 0}
  max_arg_length = step_matches.map {|step_match| step_match.args.length }.max
  top_groups     = step_matches.select {|step_match| step_match.args.length == max_arg_length }

  if no_groups.any?
    longest_regexp_length = no_groups.map {|step_match| step_match.text_length }.max
    no_groups.select {|step_match| step_match.text_length == longest_regexp_length }
  elsif top_groups.any?
    shortest_capture_length = top_groups.map {|step_match| step_match.args.inject(0) {|sum, c| sum + c.length } }.min
    top_groups.select {|step_match| step_match.args.inject(0) {|sum, c| sum + c.length } == shortest_capture_length }
  else
    top_groups
  end
end

#clear!Object



248
249
250
251
252
253
# File 'lib/cucumber/step_mother.rb', line 248

def clear!
  step_definitions.clear
  hooks.clear
  steps.clear
  scenarios.clear
end

#current_worldObject



220
221
222
# File 'lib/cucumber/step_mother.rb', line 220

def current_world
  @current_world
end

#hooksObject



170
171
172
# File 'lib/cucumber/step_mother.rb', line 170

def hooks
  @hooks ||= Hash.new {|hash, phase| hash[phase] = []}
end

#hooks_for(phase, scenario) ⇒ Object



174
175
176
# File 'lib/cucumber/step_mother.rb', line 174

def hooks_for(phase, scenario)
  hooks[phase].select{|hook| scenario.accept_hook?(hook)}
end

#register_hook(phase, tags, proc) ⇒ Object



164
165
166
167
168
# File 'lib/cucumber/step_mother.rb', line 164

def register_hook(phase, tags, proc)
  hook = Hook.new(tags, proc)
  hooks[phase] << hook
  hook
end

#register_step_definition(regexp, &proc) ⇒ Object

Registers a new StepDefinition. This method is aliased to Given, When and Then, and also to the i18n translations whenever a feature of a new language is loaded.

See Cucumber#alias_steps for details on how to create your own aliases.

The &proc gets executed in the context of a world object, which is defined by #World. A new world object is created for each scenario and is shared across step definitions within that scenario.



141
142
143
144
145
146
147
148
# File 'lib/cucumber/step_mother.rb', line 141

def register_step_definition(regexp, &proc)
  step_definition = StepDefinition.new(regexp, &proc)
  step_definitions.each do |already|
    raise Redundant.new(already, step_definition) if already.match(regexp)
  end
  step_definitions << step_definition
  step_definition
end

#scenarios(status = nil) ⇒ Object



120
121
122
123
124
125
126
127
# File 'lib/cucumber/step_mother.rb', line 120

def scenarios(status = nil)
  @scenarios ||= []
  if(status)
    @scenarios.select{|scenario| scenario.status == status}
  else
    @scenarios
  end
end

#snippet_text(step_keyword, step_name, multiline_arg_class) ⇒ Object



259
260
261
# File 'lib/cucumber/step_mother.rb', line 259

def snippet_text(step_keyword, step_name, multiline_arg_class)
  @snippet_generator.snippet_text(step_keyword, step_name, multiline_arg_class)
end

#step_definitionsObject



255
256
257
# File 'lib/cucumber/step_mother.rb', line 255

def step_definitions
  @step_definitions ||= []
end

#step_match(step_name, formatted_step_name = nil) ⇒ Object

Raises:



224
225
226
227
228
229
230
# File 'lib/cucumber/step_mother.rb', line 224

def step_match(step_name, formatted_step_name=nil)
  matches = step_definitions.map { |d| d.step_match(step_name, formatted_step_name) }.compact
  raise Undefined.new(step_name) if matches.empty?
  matches = best_matches(step_name, matches) if matches.size > 1 && options[:guess]
  raise Ambiguous.new(step_name, matches, options[:guess]) if matches.size > 1
  matches[0]
end

#step_visited(step) ⇒ Object



107
108
109
# File 'lib/cucumber/step_mother.rb', line 107

def step_visited(step)
  steps << step unless steps.index(step)
end

#steps(status = nil) ⇒ Object



111
112
113
114
115
116
117
118
# File 'lib/cucumber/step_mother.rb', line 111

def steps(status = nil)
  @steps ||= []
  if(status)
    @steps.select{|step| step.status == status}
  else
    @steps
  end
end

#World(*world_modules, &proc) ⇒ Object

Registers any number of world_modules (Ruby Modules) and/or a Proc. The proc will be executed once before each scenario to create an Object that the scenario’s steps will run within. Any world_modules will be mixed into this Object (via Object#extend).

This method is typically called from one or more Ruby scripts under features/support. You can call this method as many times as you like (to register more modules), but if you try to register more than one Proc you will get an error.

Cucumber will not yield anything to the proc (like it used to do before v0.3).

In earlier versions of Cucumber (before 0.3) you could not register any world_modules. Instead you would register several Proc objects (by calling the method several times). The result of each proc would be yielded to the next proc. Example:

World do |world| # NOT SUPPORTED FROM 0.3
  MyClass.new
end

World do |world| # NOT SUPPORTED FROM 0.3
  world.extend(MyModule)
end

From Cucumber 0.3 the recommended way to do this is:

World do
  MyClass.new
end

World(MyModule)


211
212
213
214
215
216
217
218
# File 'lib/cucumber/step_mother.rb', line 211

def World(*world_modules, &proc)
  if(proc)
    raise MultipleWorld.new(@world_proc, proc) if @world_proc
    @world_proc = proc
  end
  @world_modules ||= []
  @world_modules += world_modules
end