Skip to content

Instantly share code, notes, and snippets.

@blaix
Created July 22, 2010 13:37
Show Gist options
  • Save blaix/485974 to your computer and use it in GitHub Desktop.
Save blaix/485974 to your computer and use it in GitHub Desktop.
A modified version of the cucumber steps included in factory_girl. But I'd like to find a way to simply redefine the steps it creates without raising an ambiguos step error...
# Stolen from: http://github.com/thoughtbot/factory_girl/blob/master/lib/factory_girl/step_definitions.rb
# and slightly modified so that steps which create only a single record, save
# that record to an instance variable, so you can do things like:
#
# Given I am logged in as an admin
# And a post exists with a title of "Awesome Post"
# When I go to the post
# Then I should see "Awesome Post"
# And I should see a link to edit the post
#
# Since the Given creates a @post instance, it can be referred to like this:
#
# # paths.rb:
# when /the post/
# post_path(@post)
#
# # post_steps.rb:
# Then /^I should see a link to edit the post$/
# page.should have_xpath("//a[@href=#{edit_post_path(@post)}]")
# end
#
# This can make your steps a bit more brittle if you're not careful, but for
# me the trade-off for DRY, readable steps is worth it.
#
# Ideally I could require 'factory_girl/step_definitions.rb' and just
# redefine the steps I wanted to change, but that raises
# an ambiguous step error. Haven't figured out how to get around that yet.
# Oh well, in the meantime, I'm just dropping this in with the rest of my
# step definitions.
module FactoryGirlStepHelpers
def convert_association_string_to_instance(factory_name, assignment)
attribute, value = assignment.split(':', 2)
return if value.blank?
attributes = convert_human_hash_to_attribute_hash(attribute => value.strip)
factory = FactoryGirl.factory_by_name(factory_name)
model_class = factory.build_class
model_class.find(:first, :conditions => attributes) or
Factory(factory_name, attributes)
end
def convert_human_hash_to_attribute_hash(human_hash, associations = [])
human_hash.inject({}) do |attribute_hash, (human_key, value)|
key = human_key.downcase.gsub(' ', '_').to_sym
if association = associations.detect {|association| association.name == key }
value = convert_association_string_to_instance(association.factory, value)
end
attribute_hash.merge(key => value)
end
end
end
World(FactoryGirlStepHelpers)
Factory.factories.values.each do |factory|
Given /^the following (?:#{factory.human_name}|#{factory.human_name.pluralize}) exists?:$/ do |table|
table.hashes.each do |human_hash|
attributes = convert_human_hash_to_attribute_hash(human_hash, factory.associations)
factory.run(Factory::Proxy::Create, attributes)
end
end
Given /^an? #{factory.human_name} exists$/ do
instance_variable_set("@#{factory.factory_name.to_s}", Factory(factory.factory_name))
end
Given /^(\d+) #{factory.human_name.pluralize} exist$/ do |count|
count.to_i.times { Factory(factory.factory_name) }
end
if factory.build_class.respond_to?(:columns)
factory.build_class.columns.each do |column|
human_column_name = column.name.downcase.gsub('_', ' ')
Given /^an? #{factory.human_name} exists with an? #{human_column_name} of "([^"]*)"$/i do |value|
instance_variable_set("@#{factory.factory_name.to_s}", Factory(factory.factory_name, column.name => value))
end
Given /^(\d+) #{factory.human_name.pluralize} exist with an? #{human_column_name} of "([^"]*)"$/i do |count, value|
count.to_i.times { Factory(factory.factory_name, column.name => value) }
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment