Skip to content

Instantly share code, notes, and snippets.

@danivovich
Created March 22, 2012 01:39
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save danivovich/2155058 to your computer and use it in GitHub Desktop.
Save danivovich/2155058 to your computer and use it in GitHub Desktop.
Factory Girl steps for Turnip
module FactoryGirlStepHelpers
def convert_human_hash_to_attribute_hash(human_hash, associations = [])
HumanHashToAttributeHash.new(human_hash, associations).attributes
end
class HumanHashToAttributeHash
attr_reader :associations
def initialize(human_hash, associations)
@human_hash = human_hash
@associations = associations
end
def attributes(strategy = CreateAttributes)
@human_hash.inject({}) do |attribute_hash, (human_key, value)|
attributes = strategy.new(self, *process_key_value(human_key, value))
attribute_hash.merge({ attributes.key => attributes.value })
end
end
private
def process_key_value(key, value)
value = value.strip if value.is_a?(String)
[key.downcase.gsub(' ', '_').to_sym, value]
end
class AssociationManager
def initialize(human_hash_to_attributes_hash, key, value)
@human_hash_to_attributes_hash = human_hash_to_attributes_hash
@key = key
@value = value
end
def association
@human_hash_to_attributes_hash.associations.detect {|association| association.name == @key }
end
def association_instance
return unless association
if attributes_hash = nested_attribute_hash
factory.build_class.first(:conditions => attributes_hash.attributes(FindAttributes)) or
FactoryGirl.create(association.factory, attributes_hash.attributes)
end
end
private
def factory
FactoryGirl.factory_by_name(association.factory)
end
def nested_attribute_hash
attribute, value = @value.split(':', 2)
return if value.blank?
HumanHashToAttributeHash.new({ attribute => value }, factory.associations)
end
end
class AttributeStrategy
attr_reader :key, :value, :association_manager
def initialize(human_hash_to_attributes_hash, key, value)
@association_manager = AssociationManager.new(human_hash_to_attributes_hash, key, value)
@key = key
@value = value
end
end
class FindAttributes < AttributeStrategy
def initialize(human_hash_to_attributes_hash, key, value)
super
if association_manager.association
@key = "#{@key}_id"
@value = association_manager.association_instance.try(:id)
end
end
end
class CreateAttributes < AttributeStrategy
def initialize(human_hash_to_attributes_hash, key, value)
super
if association_manager.association
@value = association_manager.association_instance
end
end
end
end
end
FactoryGirl.factories.each do |factory|
factory.compile
factory.human_names.each do |human_name|
step "the following #{human_name} exists:" do |table|
table.hashes.each do |human_hash|
attributes = convert_human_hash_to_attribute_hash(human_hash, factory.associations)
FactoryGirl.create(factory.name, attributes)
end
end
step "the following #{human_name.pluralize} exist:" do |table|
table.hashes.each do |human_hash|
attributes = convert_human_hash_to_attribute_hash(human_hash, factory.associations)
FactoryGirl.create(factory.name, attributes)
end
end
step "a(n) #{human_name} exists" do
FactoryGirl.create(factory.name)
end
step ":count #{human_name.pluralize} exist" do |count|
FactoryGirl.create_list(factory.name, count.to_i)
end
if factory.build_class.respond_to?(:columns)
factory.build_class.columns.each do |column|
name = column.respond_to?(:name) ? column.name : column.to_s
human_column_name = name.downcase.gsub('_', ' ')
step "a(n) #{human_name} exists with a(n) #{human_column_name} of :value" do |value|
FactoryGirl.create(factory.name, name => value)
end
step ":count #{human_name.pluralize} exist with a(n) #{human_column_name} of :value" do |count, value|
FactoryGirl.create_list(factory.name, count.to_i, name => value)
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment