mirror of
				https://github.com/thoughtbot/factory_bot.git
				synced 2022-11-09 11:43:51 -05:00 
			
		
		
		
	Fixed issues with some attributes being skipped and added support for linked associations in step definitions
This commit is contained in:
		
							parent
							
								
									15f36c8fc9
								
							
						
					
					
						commit
						33b61c3bfb
					
				
					 9 changed files with 83 additions and 12 deletions
				
			
		
							
								
								
									
										1
									
								
								cucumber.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								cucumber.yml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
default: -r features features
 | 
			
		||||
| 
						 | 
				
			
			@ -18,3 +18,25 @@ Feature: Use step definitions generated by factories
 | 
			
		|||
      | title | three |
 | 
			
		||||
      | body  | third |
 | 
			
		||||
    And there should be 3 posts
 | 
			
		||||
 | 
			
		||||
  Scenario: create a post with a new author
 | 
			
		||||
    Given the following post exists:
 | 
			
		||||
      | Title  | a title |
 | 
			
		||||
      | Author | ID: 123  |
 | 
			
		||||
    Then I should find the following for the last post:
 | 
			
		||||
      | title     | a title   |
 | 
			
		||||
      | author_id | 123       |
 | 
			
		||||
    And I should find the following for the last user:
 | 
			
		||||
      | id | 123 |
 | 
			
		||||
 | 
			
		||||
  Scenario: create a post with an existing author
 | 
			
		||||
    Given the following user exists:
 | 
			
		||||
      | ID   | 123 |
 | 
			
		||||
      | Name | Joe |
 | 
			
		||||
    And the following post exists:
 | 
			
		||||
      | Title  | a title |
 | 
			
		||||
      | Author | Name: Joe |
 | 
			
		||||
    Then I should find the following for the last post:
 | 
			
		||||
      | title     | a title   |
 | 
			
		||||
      | author_id | 123       |
 | 
			
		||||
    And there should be 1 user
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,15 +1,18 @@
 | 
			
		|||
Then /^I should find the following for the last post:$/ do |table|
 | 
			
		||||
  last_post = Post.last or raise "No posts exist"
 | 
			
		||||
  attributes = table.rows.inject({}) {|res, (key, value)| res.merge(key => value) }
 | 
			
		||||
Then /^I should find the following for the last (.*):$/ do |model, table|
 | 
			
		||||
  model_class = model.camelize.constantize
 | 
			
		||||
  last_instance = model_class.last or raise "No #{model.pluralize} exist"
 | 
			
		||||
  attributes = table.raw.inject({}) {|res, (key, value)| res.merge(key => value) }
 | 
			
		||||
  attributes.each do |key, value|
 | 
			
		||||
    last_post.attributes[key].should == value
 | 
			
		||||
    last_instance.attributes[key].to_s.should == value
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
Then /^there should be (\d+) posts$/ do |count|
 | 
			
		||||
  Post.count.should == count.to_i
 | 
			
		||||
Then /^there should be (\d+) (.*)$/ do |count, model|
 | 
			
		||||
  model_class = model.singularize.camelize.constantize
 | 
			
		||||
  model_class.count.should == count.to_i
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
Before do
 | 
			
		||||
  Post.delete_all
 | 
			
		||||
  User.delete_all
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,18 +6,31 @@ ActiveRecord::Base.establish_connection(
 | 
			
		|||
class CreateSchema < ActiveRecord::Migration
 | 
			
		||||
  def self.up
 | 
			
		||||
    create_table :posts, :force => true do |t|
 | 
			
		||||
      t.integer :author_id
 | 
			
		||||
      t.string  :title
 | 
			
		||||
      t.string  :body
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    create_table :users, :force => true do |t|
 | 
			
		||||
      t.string  :name
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
CreateSchema.suppress_messages { CreateSchema.migrate(:up) }
 | 
			
		||||
 | 
			
		||||
class User < ActiveRecord::Base
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
class Post < ActiveRecord::Base
 | 
			
		||||
  belongs_to :author, :class_name => 'User'
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
Factory.define :user do |f|
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
Factory.define :post do |f|
 | 
			
		||||
  f.association :author, :factory => :user
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
require 'factory_girl/step_definitions'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,8 @@ class Factory
 | 
			
		|||
 | 
			
		||||
    class Association < Attribute  #:nodoc:
 | 
			
		||||
 | 
			
		||||
      attr_reader :factory
 | 
			
		||||
 | 
			
		||||
      def initialize(name, factory, overrides)
 | 
			
		||||
        super(name)
 | 
			
		||||
        @factory   = factory
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -305,6 +305,10 @@ class Factory
 | 
			
		|||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def associations
 | 
			
		||||
    attributes.select {|attribute| attribute.is_a?(Attribute::Association) }
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
  def class_for (class_or_to_s)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,14 +1,25 @@
 | 
			
		|||
module FactoryGirlStepHelpers
 | 
			
		||||
  def convert_ast_table_to_attribute_hash(table)
 | 
			
		||||
    table.rows.inject({}) do |result, (human_key, value)|
 | 
			
		||||
      key = human_key.downcase.gsub(' ', '_').to_sym
 | 
			
		||||
  def convert_vertical_table_to_hash(table)
 | 
			
		||||
    table.raw.inject({}) do |result, (key, value)|
 | 
			
		||||
      result.merge(key => value)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def convert_human_hash_to_attribute_hash(human_hash)
 | 
			
		||||
  def convert_association_string_to_instance(factory_name, assignment)
 | 
			
		||||
    attribute, value = assignment.split(':', 2)
 | 
			
		||||
    attributes = convert_human_hash_to_attribute_hash(attribute => value.strip)
 | 
			
		||||
    factory = Factory.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
 | 
			
		||||
| 
						 | 
				
			
			@ -18,14 +29,15 @@ World(FactoryGirlStepHelpers)
 | 
			
		|||
 | 
			
		||||
Factory.factories.values.each do |factory|
 | 
			
		||||
  Given "the following #{factory.human_name} exists:" do |table|
 | 
			
		||||
    attributes = convert_ast_table_to_attribute_hash(table)
 | 
			
		||||
    human_hash = convert_vertical_table_to_hash(table)
 | 
			
		||||
    attributes = convert_human_hash_to_attribute_hash(human_hash, factory.associations)
 | 
			
		||||
    Factory.create(factory.factory_name, attributes)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # TODO: support irregular pluralizations
 | 
			
		||||
  Given "the following #{factory.human_name}s exist:" do |table|
 | 
			
		||||
    table.hashes.each do |human_hash|
 | 
			
		||||
      attributes = convert_human_hash_to_attribute_hash(human_hash)
 | 
			
		||||
      attributes = convert_human_hash_to_attribute_hash(human_hash, factory.associations)
 | 
			
		||||
      Factory.create(factory.factory_name, attributes)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,6 +12,10 @@ describe Factory::Attribute::Association do
 | 
			
		|||
    @attr.name.should == @name
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "should have a factory" do
 | 
			
		||||
    @attr.factory.should == @factory
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "should tell the proxy to associate when being added to a proxy" do
 | 
			
		||||
    proxy = "proxy"
 | 
			
		||||
    stub(proxy).associate
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -134,6 +134,16 @@ describe Factory do
 | 
			
		|||
      factory.attributes.should include(attr)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "should return associations" do
 | 
			
		||||
      factory = Factory.new(:post)
 | 
			
		||||
      factory.association(:author)
 | 
			
		||||
      factory.association(:editor)
 | 
			
		||||
      factory.associations.each do |association|
 | 
			
		||||
        association.should be_a(Factory::Attribute::Association)
 | 
			
		||||
      end
 | 
			
		||||
      factory.associations.size.should == 2
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "should add an association with overrides" do
 | 
			
		||||
      factory   = Factory.new(:post)
 | 
			
		||||
      name      = :user
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue