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



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

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

#After(*tag_names, &proc) ⇒ Object



154
155
156
# File 'lib/cucumber/step_mother.rb', line 154

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

#after_stepObject



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

def after_step
  execute_after_step(@current_scenario)
end

#AfterStep(*tag_names, &proc) ⇒ Object



158
159
160
# File 'lib/cucumber/step_mother.rb', line 158

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

#before(scenario) ⇒ Object



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

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).



150
151
152
# File 'lib/cucumber/step_mother.rb', line 150

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

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

Yields:

  • (scenario)


257
258
259
260
261
262
263
264
# File 'lib/cucumber/step_mother.rb', line 257

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



230
231
232
233
234
235
236
237
238
239
240
# File 'lib/cucumber/step_mother.rb', line 230

def best_matches(step_name, step_matches)
  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 top_groups.length > 1
    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



242
243
244
245
246
247
# File 'lib/cucumber/step_mother.rb', line 242

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

#current_worldObject



218
219
220
# File 'lib/cucumber/step_mother.rb', line 218

def current_world
  @current_world
end

#hooksObject



168
169
170
# File 'lib/cucumber/step_mother.rb', line 168

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

#hooks_for(phase, scenario) ⇒ Object



172
173
174
# File 'lib/cucumber/step_mother.rb', line 172

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

#register_hook(phase, tags, proc) ⇒ Object



162
163
164
165
166
# File 'lib/cucumber/step_mother.rb', line 162

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.

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.



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

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



253
254
255
# File 'lib/cucumber/step_mother.rb', line 253

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

#step_definitionsObject



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

def step_definitions
  @step_definitions ||= []
end

#step_match(step_name, formatted_step_name = nil) ⇒ Object

Raises:



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

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)


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

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